#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "vfs.h"
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <string.h>
#include "if_v.h"
#include "limoi-video-src03.h"
#include "limoi-video-src02_vis.h"
#include "limoi-video-src02_ir.h"
#include "match.h"


#include "aos/kernel.h"
#include "aos/yloop.h"
//#include <k_types.h>
//#include <k_err.h>
#include "time.h"
#include <csky_common.h>
#include "drv_isp.h"
#include <pin.h>
#include "drv_gpio.h"   
#include "pin_name.h" 
// #include <csi_config.h>
#include "cam_engine_api.h"
#include "cam_engine_aaa_api.h"
#include "hal/hal_api.h" 
#include "ulog/ulog.h"
#include "aos/hal/i2c.h"
#include "aos/hal/mipi_csi.h"
#include "camera_config.h"
#include "mm_config.h"
#include "drv_isp.h"
#include "cam_engine_ctrl.h"
#include "image_proc.h"
#include "iic_function.h"
#include "isp_function.h"
#include "mipi_function.h"
#include "image_task.h"
//#include "test_hist/test_hist.h"
#include "wrapper.h"
#include "image_proc.h"

#include "img_cli_deal.h"
#include "para_traverse_task.h"

#include "debug_perf.h"
#include "faceproc.h"

#include "pthread.h"
#include "lvgl.h"

#include "debug_time.h"
#include "lv_port_disp.h"
//#include "uart_task/uart_packet.h"
#include "dpu.h"
// #include "face_screen.h"
#include <fcntl.h>
#include "vfs.h"

//#include "jpegConvert.h"
#include "jpeglib.h"
#include "jerror.h"
#include "JpegTable.h"
//#include "tmeshhandle.h"

//#include "test_jpg.h"

#include "pic_crop.h"
//#include "dconfig.h"
#include "aec.h"
#include "aos/kv.h"
//#include "analysislog.h"
#include "jpegConvert.h"
#include "net_param.h"
#include "cam_engine_cproc_api.h"
#include "cam_engine.h"

#include "rectify_param.h"
#include "userFaceSample.h"
#include "ff_mgr.h"
#include "board.h"
#include "aos/kernel.h"
#include "board_sensor.h"
#include "cam_engine_isp_api.h"
#include "image_task.h"
#include "uart_task.h"

#define TAG "ifv"
typedef enum _PACK_MSG_STATE_E
{
    MS_STANDBY = 0, // IDLE, waiting for commands
    MS_BUSY = 1,    // in working of processing commands
    MS_ERROR = 2,   // in error state. can't work properly
    MS_INVALID = 3, // not initialized
    MS_OTA = 4,     // in ota state

}MsgState_e;

#define OMX_IR_PORT_IDX  0
#define OMX_SPK_PORT_IDX  0

#define OMX_LEFT_IR_PORT_IDX  0
#define OMX_RIGHT_IR_PORT_IDX 1

#define OMX_RGB_PORT_IDX 0

//#define REGISTER_IR_ENABLE 1
extern uint8_t register_by_ir;
uint32_t register_ir_nir_living_flag = 1;
aos_event_t recognizeEvents;

pthread_cond_t  register_cond;
pthread_mutex_t register_mutex;
int register_flag=0;	
uint8_t isp_rgb_enable_flag = 1;
int startRegisterCmd;
#if defined(AOS_APP_LAMP_GC1054)
#include "lamp_cli.h"
extern int aie_vis_pose_enable;
extern lampThresh_t lampThresh;
extern tsmDeviceParam lampDevicePara;
#endif

aos_timer_t     g_double_ir_mi_rx_timer;
extern int g_irSensorLeftCapMode;
extern int g_irSensorRightCapMode;

int g_isp_idx[ISP_NUM] = {0,1,2};

//int ifv_debug_level = IFV_MSG_ERROR;
extern 	int ifv_debug_level; //= IFV_MSG_ERROR;
long long ifv_start_time =0;
long long ifv_stop_time = 0;
int g_scenario_type = SENSOR_EXPO_INDOOR;
int g_usbRecogState=0;
int g_rgbSensorCapMode = 0;
int g_irSensorConvergent[ISP_NUM] = {0};
int g_sensorConvergentCount=0;
int g_irLumaConvergent=0;
extern float faceBoxXmin;
extern float faceBoxYmin;
extern float faceBoxXmax;
extern float faceBoxYmax;
extern TsmHandle AIE_handle;
aos_mutex_t g_isp_3a_mutex;

extern int g_register_once_one_person;

extern int g_face_ae_ok;
int ifv_register_mode;
bool if_vFaceRecogEvent(int sensorID, void *pData);
bool if_v3DdetectEvent(int sensorID, void *pData);
bool if_vVisDetectEvent(int event, void *pData);

extern uint8_t *iva_2ir_get_buffer(uint32_t , uint32_t );
extern void cis_aelock_save(uint32_t idx);
extern void registerFromUartAck(uint32_t result,uint32_t id);
extern int if_vCalibration_save(void);
extern void userCmdGetIrSpkSnapShot(int led_type);
extern void delUserResultAck(uint32_t flag,int result,uint16_t id);
extern void dump_le_uint16(uint8_t *addr, uint16_t *value);
extern int aos_task_delete(char *name);
extern void qw_isp_ae_enable_set(uint32_t isp_id, bool flag);
extern void iva_2ir_empty_buffer(int, int);
extern void iva_facereco_spk_empty_buffer(int, int);
extern void iva_tof_reco_ir_empty_buffer(int, int);
extern int IspEngineConfigStartSetPoint(uint32_t isp_id, float setpoint);
extern void omx_init(ifvOpenmaxEventHandler_t *);
extern void omx_facereco_visstream(void);
extern void omx_facereco_aieinit(void);
extern void omx_facereco_sl3dinit(void);
extern void omx_facereco_vis(void);
extern void omx_cat_eye(void);
extern void cfg_cat_eye_mi_buffer();
extern void omx_facereco_ir(uint32_t, uint32_t);
extern void omx_facereco_2ir(uint32_t, uint32_t);
extern void omx_dual_ir_preview(uint32_t, uint32_t);
extern void omx_preview_cap(uint32_t, uint32_t);
extern void iva_ir_empty_buffer(uint32_t, uint32_t);
extern void iva_spk_empty_buffer(uint32_t, uint32_t);
extern void iva_uvc_empty_buffer(uint32_t, uint32_t);
extern void iva_dual_ir_empty_buffer(uint32_t, uint32_t);
extern void iva_cat_eye_empty_buffer(uint32_t, uint32_t);
extern void iva_facereco_ir_empty_buffer(uint32_t, uint32_t);
extern void isp_cfg_single_buffer(int isp_idx);
extern void omx_facereco_tof(void);
extern void isp_cfg_preview_trangle_buffer(int isp_idx,uint32_t width,uint32_t height);
extern int ifv_ISP_task_creat(void);
extern void delAllResultAck(int result);
extern int get_user_info_by_id(uint16_t user_id, uint8_t *name, uint8_t *admin);
extern void MsgGetUserInfoReply(uint16_t id, uint8_t* name,uint8_t admin,uint8_t result);
extern void MsgNoDataReply(uint8_t cmd,uint8_t result);
extern void clearAEConvergentStatus();
extern void qw_isp_ae_lock_judge_set(uint32_t isp_id, bool flag);
extern void vi_isp_buffer_set(uint32_t idx, uint32_t reg, uint32_t address);
extern void recognizeResultAck(int result,uint16_t id);
extern int if_vReadIrSpkDataFromISP();
extern int ir_led_power_off(void);

ifvOpenmaxEventHandler_t ifv_cb[]={
            {OPENMAX_SOURCE_VIS_EVENT,      	if_v_source_vis_event_callback},
			{OPENMAX_SOURCE_IR_CAP_EVENT,   	if_v_source_ir_event_callback}, 
			{OPENMAX_VISIBLE_REGISTER_EVENT,	if_v_Register_vis_event_callback},
			{OPENMAX_IR_RECOGNIZE_EVENT,    	if_v_Recognize_ir_event_callback},
		    {OPENMAX_DOUBLE_IR_RECOGNIZE_EVENT,	if_v_Recognize_double_ir_event_callback},
		    {OPENMAX_TOF_IR_RECOGNIZE_EVENT,  	tof_Recognize_event_callback},
		    {OPENMAX_FACE_RECOG_EVENT,      	(void (*)(int, void *))if_vFaceRecogEvent},
		    {OPENMAX_3D_DETECT_EVENT,       	(void (*)(int, void *))if_v3DdetectEvent},
		    {OPENMAX_VIS_DETECT_EVENT,      	(void (*)(int, void *))if_vVisDetectEvent},
		    {OPENMAX_SOURCE_SPK_CAP_EVENT,  	if_v_source_spk_event_callback}
	};



aos_timer_t g_ifv_test_timer;
extern uint8_t mipiWorkStatusFlag;
extern void omx_register_from_IFV(OMX_U8* pBuffer, int size);
extern volatile int isp_mi_event[ISP_NUM];
static uint32_t g_snapshot_3in1_m = SNAPSHOT_MODE_3IN1_VIS_IR;

float FACE_PROC_THRES_DEF_2D = 0.52;
float FACE_PROC_THRES_DEF_3D = 0.001;
//#define FACE_PROC_THRES_DEF_RECOG 0.1733
float FACE_PROC_THRES_DEF_RECOG_MASK = 0.12;
float HEAD_POSE_THRES_X = 30.0;
float HEAD_POSE_THRES_Y = 30.0;

living_detection_config IF_v_living_defconfig={0.5,0.5,0};
face_detect_config IF_v_face_detect_defconfig={1,0.0,1,0.0};
unsigned char ifvRandomKey[16] = {0};
int g_ifVsaveRgbEnable;
int g_ifVsaveIrEnable;
int g_ifVUnmaskEnable = false;
float g_RecoMaxScore=0.0f;
int g_ifVispMiInTEnable=0;
int g_omx_debug=1;
if_v_sema_t ifvDataSemp_isp_rgb; 
if_v_sema_t ifvDataSemp_isp0; 
if_v_sema_t ifvDataSemp_isp_ir;
if_v_sema_t ifvDataSemp_isp_spk;

if_v_sema_t ifvRecongIrSemp;
if_v_sema_t ifvCmd2OpenmaxSemp;
if_v_sema_t ifvDataIrSpkSemp_isp;
if_v_sema_t ifvSnapDataSemp_isp;

#if 1  //DOUBLE_IR_ENABLE
if_v_sema_t ifvDataSemp_isp0_mi0;
if_v_sema_t ifvDataSemp_isp1_mi0;
if_v_sema_t ifvDataSemp_isp2_mi0;
#endif


if_v_sema_t ifv_cmd_sem_task;

if_v_sema_t ifvJpegRegisterSem;

if_v_sema_t ifv_mi_ir_rgb_semp;

if_v_sema_t ifv_usb_semp;

int aie_vis_detect_enable = 0;
int aie_vis_reco_enable = 0; 
uint32_t g_uvc_preview_mode_enable = false;
extern uint8_t dma_cb_flag;

uint32_t g_recog_repeat_interval = 0;
aos_timer_t timer_recog_ratelimit;
uint32_t g_recog_repeat_suppress = false;
uint32_t g_curr_recog_id = 0xffffffff;


#define FACE_MATCH_SCORE_ENABLE 1
#define ISP_RGB_ID 0
#define ISP_IR_ID 1

//struct list_head g_ifv2openmax_cmd_list = LIST_HEAD_INIT(g_ifv2openmax_cmd_list);
static AOS_DLIST_HEAD(g_ifv2openmax_recognize_cmd_list);
cmd2openmax_list g_ifv2openmax_recognize_cmd={0,0,0,{NULL, NULL}}; 

static AOS_DLIST_HEAD(g_ifv2openmax_register_cmd_list);
cmd2openmax_list g_ifv2openmax_register_cmd={0,0,0,{NULL, NULL}}; 

static AOS_DLIST_HEAD(g_ifv2openmax_jpeg_register_cmd_list);
cmd2openmaxJpeg_list g_ifv2openmax_jpeg_register_cmd;

openMaxSrcDesc openMaxSrcModeGroup[]={
	{VIDEO_SRC03_MODE_IR, (unsigned char *)"VIDEO_SRC03_MODE_IR"},
	{VIDEO_SRC03_MODE_SPECKLE, (unsigned char *)"VIDEO_SRC03_MODE_SPECKLE"},
	{VIDEO_SRC03_MODE_VIS, (unsigned char *)"VIDEO_SRC03_MODE_VIS"},
	{VIDEO_SRC03_MODE_JPEG, (unsigned char *)"VIDEO_SRC03_MODE_JPEG"},
	{VIDEO_SRC03_MODE_NONE, (unsigned char *)"VIDEO_SRC03_MODE_NONE"}

};

extern void MsgGetAllUserId(uint8_t count,uint8_t *userid,uint8_t result);
extern int IspEngineConfigStartEXP(uint32_t isp_id, float exp);
extern int sensor_reinit();
extern void ifv_load_aie_thres(float *thres_2d, float *thres_3d, float *thres_recog, float *thres_recog_mask);
extern void isp_reset(int32_t idx);
void if_vNotifyVisIspData(int isp_id);
void if_vRecognition_process(unsigned char * card_number, app2if_v_cb *info,  int timeout);
void ifv_wait_usb_semp(void);
void if_vNotifyIspSpkData();
void if_vNotifyIspSnapData(int isp_id);
int ifv_ISP_cat_eye_interrupt_task_creat(void);
int ifv_ISP_MI_interrupt_task_creat(void);

volatile uint32_t curFaceNum = 0;
volatile uint32_t curFaceID = 0;
static volatile uint32_t curOffset = 0;
//uint32_t *pFaceNum = FACE_NUM_ADR;
//uint32_t *pFaceId = FACE_ID_ADR;
static volatile uint32_t totalFaceNum = 500;
uint8_t *faceFeature = NULL;
uint8_t *faceMaskFeature = NULL;

uint32_t register_ir_flag = 0;
uint32_t aie_ir_detect_enable = 0;

uint8_t g_multiAngleRegister = 0;

extern uint32_t *g_fb_rgb[];
extern uint32_t *g_fb_ir[] ;
extern uint32_t *g_fb_spk_right[];
extern uint32_t *g_fb_spk_left[] ;
extern uint32_t g_fb_buffer_group_id;


UserCmdCB *userCmdArrayCB=NULL;


uint32_t gIfvRuningState = IFV_RUNNING_STATE_NONE;
 	
MeanLumaSceneJudgeConfig_s lumaCfg={
	.thd_max_h = 255,
	.thd_max_l = 90,
	.thd_min_h = 50,
	.thd_min_l = 0,
	.scene = SENSOR_EXPO_INDOOR};

data_flow_func_control_t g_ifv_flow_cfg = {0};
g_variable_control_t g_variable_cfg = {0};


ifv_sensor_func_s g_ifv_sensor_func = {0}; 
int g_sys_init_done = false;
char *g_ifv_pic_register = NULL;
char *srcImgAddr = NULL;
char *g_resize_pic = NULL;

int g_vis_buffer_num = 0;
uint8_t *g_vis_buffer[8] = {NULL};
uint8_t *g_tx_vis_buff = NULL;
bool g_tx_enable_flag = true;
int irreco_enable_flag = 0;
int irreco_exp_init_done = 0;
float irreco_exp = 0.0f;
float irreco_set_point = 0.0f;


int g_reco_result = USERCMDRECOGNIZERESULT_NONE;
int g_reco_id = 0xffffffff;
bool g_passlog_en = true;
ifv_face_ae_info_s g_face_ae_info = {0};

#ifdef BCTC_TEST
Bctc_s g_bctc = {
	.faceImage = NULL,
	.result = 0,
	.xmin = 0,
	.ymin = 0,
	.xmax = 0,
	.ymax = 0,
};
#endif
/*************************************************************************************/
#if 0
int depthMapCountLuma(float x_min,float y_min,float x_max,float y_max,uint16_t *img)
{
	int i,j = 0;
	int xmin,ymin,xmax,ymax = 0;
	uint32_t totalVal = 0;
	uint32_t count = 0;
	float averageVal = 0.0;
	xmin = x_min < 0 ? 0 : ceil(x_min);
	ymin = y_min < 0 ? 0 : ceil(y_min);
	xmax = x_max < 0 ? 0 : ceil(x_max);
	ymax = y_max < 0 ? 0 : ceil(y_max);

	for(i=xmin;i<xmax;i+=4)
	{
		for(j=ymin;j<ymax;j+=4)
		{
			count++;
			totalVal += *(img+i+j*360);
		}
	}

	averageVal = (float)totalVal/count;

	return ceil(averageVal);
}
#endif

void* if_vAligned_malloc(size_t size, size_t alignd_byte)
{
	size_t offset = sizeof(void *) + alignd_byte - 1; 
	void* q = aos_malloc(size + offset);
	if (!q)
		return NULL;

	void* p = (void *)(((size_t)(q)+offset) & ~(alignd_byte - 1));
	*(((void **)p) - 1) = q;

	return p;
}

void if_vAligned_free(void* p)
{
	void* q = ((void **)p)[-1];
	aos_free(q);
}


void recoMatchTest(uint8_t *ff_pool, uint8_t *feat)
{
	for(int i=0; i<5; i++)
	{
        int feature_len=ONE_FACE_FEATURE_SIZE;
		printf("f_len %d\n",feature_len);
		short *ff = (short *) (ff_pool + i * feature_len * sizeof(short));
		float score = MatchFixed((short *)feat, ff, feature_len, 12);
		printf("(%d)similarity: %f\n",i, score);
	}
}

int getRecoMaxSimilarityId(TsmFaceResult *result, uint8_t *ff_pool, int face_id)
{
	int max_id = -1;
	float max_score = 0.0f;
	int id[100];
	int id_index = 0;
    short *vec = NULL;
	uint32_t *match_bitpool = result->match.bitBool +  result->match.len*face_id;
	for(int k=0;k<(g_ifv_flow_cfg.max_face_num+31)/32;k++)
	{
		for(int m=0; m<32 && k*32+m < g_ifv_flow_cfg.max_face_num; m++)
		{
			if(((match_bitpool[k] >> m) & 0x01))
			{
				if(id_index<(100-1))
					id[id_index++] = k*32+m;
//				else
//					LOGD(TAG, "Warning: More misidentification!!! \n");
			}
		}
	}

	//LOGD(TAG, "id_index: %d\n",id_index);
	
	if(id_index > 10)
		LOGD(TAG, "Warning: More misidentification!!! \n");

#define FF_Q 12
    if(result->qa[0].mask)
        vec = result->mask_feature.vector + face_id*FACE_FEATURE_LENGTH;
    else
	    vec = result->feature.vector + face_id*FACE_FEATURE_LENGTH;
    
	for(int i=0; i<id_index; i++)
	{
        if(i>=(100-1))
        {
            break;
        }
        
		short *ff = (short *) (ff_pool + id[i] * ONE_FACE_FEATURE_SIZE * sizeof(short));
		float score = MatchFixed(vec, ff, ONE_FACE_FEATURE_SIZE, FF_Q);
		LOGD(TAG, "(%d)similarity: %f\n",id[i], score);
		if(score > max_score)
		{
			max_id = id[i];
			max_score = score;
		}
	}

	// Match *match = NULL;
	// match = createMatch(ff_pool,15,512,12);
	// for(int j=0;j<15;j++)
	// {
	// 	LOGD(TAG, "matchScore %d : %f \n" , j, doMatchFixed(match,vec,j,12));
	// }
#if 0
    g_RecoMaxScore = max_score;
	if( (-1 != max_id) && (true == g_ulIfvDebugEnable)){
		sprintf(recog_match, "%f",g_RecoMaxScore);
	}
#endif
	return max_id;
}
#if 0
int ALr_getRecoMaxSimilarityId(TsmFaceResult *result, uint8_t *ff_pool, int face_id)
{
	int max_id = -1;
	float max_score = 0.0f;
	//int id[100] = {0};
	static int id[10000] = {0};
	int id_index = 0;
    short *vec = NULL;
	int k = 0;
	int m = 0;
	uint32_t *match_bitpool = result->match.bitBool +  result->match.len*face_id;

	uint64_t time0 = aos_now_ms();
	recog_match_result = 0;
	for( k=0;k<(MAX_FACE_NUM+31)/32;k++)
	{
		//LOGD(TAG, ">>>>k=%d\n", k);
		for(m=0; m<32 && k*32+m < MAX_FACE_NUM; m++)
		{		
			if(id_index<(10000-1)){
				id[id_index++] = k*32+m;	
			}

			if(((match_bitpool[k] >> m) & 0x01))
			{
				recog_match_result = 1;
			}
		}
	}
	uint64_t time1 = aos_now_ms();
	LOGD(TAG, "id_index: %d\n",id_index);
	
	// if(id_index > 10)
	// 	LOGD(TAG, "Warning: More misidentification!!! \n");

#define FF_Q 12
    if(result->qa[0].mask)
        vec = result->mask_feature.vector + face_id*FACE_FEATURE_LENGTH;
    else
	    vec = result->feature.vector + face_id*FACE_FEATURE_LENGTH;
    
	uint64_t time2 = aos_now_ms();
	for(int i=0; i<id_index; i++)
	{
		short *ff = (short *) (ff_pool + id[i] * FACE_FEATURE_LENGTH * sizeof(short));
		float score = MatchFixed(vec, ff, FACE_FEATURE_LENGTH, FF_Q);
		//LOGD(TAG, "(%d)similarity: %f\n",id[i], score);
		if(score > max_score)
		{
			max_id = id[i];
			max_score = score;
		}
	}
	uint64_t time3 = aos_now_ms();
	// Match *match = NULL;
	// match = createMatch(ff_pool,15,512,12);
	// for(int j=0;j<15;j++)
	// {
	// 	LOGD(TAG, "matchScore %d : %f \n" , j, doMatchFixed(match,vec,j,12));
	// }
	LOGD(TAG, ">>>>for1:%llu, for2:%llu\n", time1-time0, time3-time2);
    g_RecoMaxScore = max_score;
	//memset(recog_match, 0,sizeof(recog_match));
	//sprintf(recog_match, "%f",g_RecoMaxScore);	
	return max_id;
}
#endif



int vis_reco_event(TsmFaceResult *tp)
{
	CmdRecognizeCBinfo_S userInfo;
	LOGD(TAG, "%s\n",__FUNCTION__);
	if(tp->nFace == 0)
	{
		userInfo.result = FACE_RESULT_NO_FACE;
		userInfo.id = 0xffffffff;
		userCmdArrayCB[1].pfuncmd(&userInfo);
	}
	else if(tp->nFace == 1)
	{
#if 0	//debug
		for(int i=0;i<tp->nFace;i++)
		{
            int ret = 0; 
            char *str, *str_sub;
            
			LOGD(TAG, "# NO. %d \n",i+1);
			pBox = (tp->box + i);
            faceBoxXmin = 360*pBox->xmin;
            faceBoxYmin = 360*pBox->xmin;
            faceBoxXmax = 360*pBox->xmax;
            faceBoxYmax = 640*pBox->ymax;
			LOGD(TAG, "vis face : xmin :%f, ymin :%f, xmax :%f, ymax :%f \n",(360*pBox->xmin),(360*pBox->xmin),(360*pBox->xmax),(640*pBox->ymax));
			//LOGD(TAG, "1c:%f *\n", tp->scoreVis[i]);
			LOGD(TAG, "pose xyz %f,%f,%f \n", tp->qa[i].pose[0], tp->qa[i].pose[1], tp->qa[i].pose[2]);

			if(g_ulIfvDebugEnable){				
				//memset(recog_xyz, 0,sizeof(recog_xyz));
				//memset(recog_score, 0,sizeof(recog_score));
				sprintf(recog_xyz, "%f,%f,%f",tp->qa[i].pose[0], tp->qa[i].pose[1], tp->qa[i].pose[2]);	
				sprintf(recog_score, "3d:%f 2d:%f 1d:NA",tp->scoreLive3D[i], tp->scoreNir[i]);
			}	

#if 0
			if(tp->qa[i].pose[0] > 30 
                || tp->qa[i].pose[0] < -30 
                || tp->qa[i].pose[1] > 20
                || tp->qa[i].pose[1] < -20)
#else
            ret += device_config_get_value("setting","pic_jdgsth","FACE_ALGORITHM_QUALITY_CHECK_TOGGLE",&str);
            ret += device_config_get_value("setting","pic_jdgsth","FACE_ALGORITHM_QUALITY_ANGLE_CHECK_TOGGLE",&str_sub);
            if ((tp->qa[i].bad_posture)
                && (ret == 0) 
                && (0 == strcmp(str, "true"))
                && (0 == strcmp(str_sub, "true")))
            {
                //lv_write_myFontsimsun28_messageid(FACERECOG_MSG_VERIFY_WRONGWAY, 0);
                codec_send(face_screen, sizeof(face_screen)/sizeof(char));
				LOGD(TAG, "please move your head. \n");
			}
#endif
		}
#endif
		if (tp->qa[0].bad_posture)
		{
			return 0;
		}
#if 0      
		if( (true == g_ulIfvDebugEnable)  && (true == alr_matcherr_neec_id_score) ){
			userInfo.id = ALr_getRecoMaxSimilarityId(tp, faceFeature, 0); //suport only one biger face
			if(recog_match_result){
			userInfo.result = USERCMDRECOGNIZERESULT_SUCCESS;
		    LOGD(TAG, "recognize suc id: %d \n", userInfo.id);

			}else{
				userInfo.result = USERCMDRECOGNIZERESULT_FACEMATCHERR;
				LOGD(TAG, "recognize match fail max similar id: %d \n", userInfo.id);
				//userInfo.id = 0xffffffff;	
			}
		}
		else
#endif
		{
			userInfo.id = getRecoMaxSimilarityId(tp, faceFeature, 0); //suport only one biger face
			if(userInfo.id == -1)
			{
				userInfo.result = FACE_RESULT_NOT_MATCH;
				userInfo.id = 0xffffffff;
			}
			else
			{
				userInfo.result = FACE_RESULT_SUCCESS;
				LOGD(TAG, "recognize id: %d \n", userInfo.id);
			}
		}
			
		userCmdArrayCB[1].pfuncmd(&userInfo);	
	}
	else if(tp->nFace > 1)
	{
		LOGE(TAG, "Warning: reco faces more than one\n");			
		userInfo.result = FACE_RESULT_FACE_MORE;
		userInfo.id = 0xffffffff;
		userCmdArrayCB[1].pfuncmd(&userInfo);
	}
	else{
		LOGE(TAG, "Warning: not support! \n");	
	}
	
	return 0;
}

extern uint32_t enroll_or_recognize_busy_flag;
extern uint32_t enroll_from_uart_busy_flag;
extern uint32_t living_3d_flag;
extern int g_ir_luma;
extern int g_aie_init_flag;
extern uint32_t tRecogizeStart;
extern uint32_t tRecogize;
extern int g_aie_init_ff;
extern uint32_t g_ir_live_enable;
extern aos_mutex_t g_aie_mutex;

void if_vFlowStateReset(int idx)
{
	cmd2openmax_list *cmd2openmax_recog = &g_ifv2openmax_recognize_cmd;
	cmd2openmax_list *cmd2openmax_register = &g_ifv2openmax_register_cmd;

	isp_reset(idx);
	
#if defined(AOS_APP_LOCK_APP) || defined(AOS_APP_BCTC_APP)
	int ret = 0;
	//if (g_ifv_flow_cfg.source_spk)
	{
		ifv_printf(IFV_MSG_ERROR,"%s reinit sensor \r\n", __func__);
		ret = sensor_reinit();
	}
#endif 	
	
	TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_INDOOR;
	TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_IR;
	cmd2openmax_recog->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
	cmd2openmax_register->state = APP2IFV_REGISTER_CMD_STATE_COMPLETE;

	enroll_or_recognize_busy_flag=0;
	enroll_from_uart_busy_flag=0;
}

void if_v_visible_event_callback(int event, void *data)
{
	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);

}


void ut_if_v_Recognize_vis_event_callback()
{
    TsmFaceResult stData;
    stData.feature.len = 512;
    stData.feature.vector = (int16_t *)aos_malloc(1024);
    stData.feature.vector[0] = 0x1234;
    stData.feature.vector[1] = 0x5678;
    stData.nFace = 1;
    
    if_v_Register_vis_event_callback(0, &stData);
}

void printAIResult(TsmFaceResult *result)
{
	TsmFaceResult *tp = result;
	TsmFaceBox *pBox = NULL;
	
	if (!tp->nFace)
	{
		//LOGD(TAG, "No face!!!\r\n");
		return;
	}
	else
	{
		for(int i=0;i<tp->nFace;i++)
		{
			LOGD(TAG, "# NO. %d \n",i+1);
			pBox = (tp->nirBox + i);

			LOGD(TAG, "nir face : xmin :%f, ymin :%f, xmax :%f, ymax :%f \n",(360*pBox->xmin),(640*pBox->ymin),(360*pBox->xmax),(640*pBox->ymax));
			LOGD(TAG, "3d:%d 2d:%d \n", tp->sl3dCheckFailed[i], tp->nirCheckFailed[i]);
			LOGD(TAG, "3c:%f 2c:%f 1c:%f *\n", tp->scoreLive3D[i], tp->scoreNir[i], tp->scoreVis[i]);
			LOGD(TAG, "pose xyz %f,%f,%f \n", tp->qa[i].pose[0], tp->qa[i].pose[1], tp->qa[i].pose[2]);
			//LOGD(TAG, "pose cover: %d ,score %f\n", tp->qa[i].cover, tp->socreVisNc[i]);
			LOGD(TAG, "pose[0]:%f pose[1]:%f\n",fabs(tp->qa[i].pose[0]),fabs(tp->qa[i].pose[1]));
			if(tp->qa[i].bad_posture){
				LOGD(TAG, "please move your head. \n");
			}
			
			break;
		}
	}
}
#if 0
static float g_ir_set_point = 0;
static uint32_t g_ir_face_luma_mean = 0;
void if_v_getIrImageBuffer(uint32_t isp_idx, char **imgBuf)
{
    if (g_ifv_flow_cfg.source_ir_right)
    {
        uint32_t buffer_idx = 0;
        
        if ((ISP_2 == isp_idx) || (ISP_1 == isp_idx))
        {
            buffer_idx = 1;
        }
        
        *imgBuf = iva_2ir_get_buffer(buffer_idx, 0);
        //LOGD(TAG, "%s %d idx: %d, imgBuf: 0x%x\r\n", __func__, __LINE__, isp_idx, *imgBuf);
    }
    else
    {
        *imgBuf = iva_facereco_ir_get_buffer(0, 0);
    }

    return;
}
#endif

#if 1
int32_t if_vGetRotateLuma(int32_t idx, uint8_t aec_exp_means[][5])
{
    if (!TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].rotate
        && !TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].v_flip
        && !TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].h_flip)
    {
        aec_exp_means[0][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_00);
        aec_exp_means[0][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_10);
        aec_exp_means[0][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_20);
        aec_exp_means[0][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_30);
        aec_exp_means[0][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_40);
        
        aec_exp_means[1][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_01);
        aec_exp_means[1][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_11);
        aec_exp_means[1][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_21);
        aec_exp_means[1][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_31);
        aec_exp_means[1][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_41);
        
        aec_exp_means[2][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_02);
        aec_exp_means[2][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_12);
        aec_exp_means[2][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_22);
        aec_exp_means[2][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_32);
        aec_exp_means[2][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_42);
        
        aec_exp_means[3][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_03);
        aec_exp_means[3][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_13);
        aec_exp_means[3][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_23);
        aec_exp_means[3][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_33);
        aec_exp_means[3][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_43);
                                                                        
        aec_exp_means[4][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_04);
        aec_exp_means[4][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_14);
        aec_exp_means[4][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_24);
        aec_exp_means[4][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_34);
        aec_exp_means[4][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_44);
    }
    else if (TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].rotate
        && !TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].v_flip
        && !TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].h_flip)
    {
        aec_exp_means[0][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_40);
        aec_exp_means[0][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_41);
        aec_exp_means[0][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_42);
        aec_exp_means[0][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_43);
        aec_exp_means[0][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_44);
        
        aec_exp_means[1][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_30);
        aec_exp_means[1][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_31);
        aec_exp_means[1][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_32);
        aec_exp_means[1][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_33);
        aec_exp_means[1][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_34);
        
        aec_exp_means[2][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_20);
        aec_exp_means[2][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_21);
        aec_exp_means[2][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_22);
        aec_exp_means[2][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_23);
        aec_exp_means[2][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_24);
        
        aec_exp_means[3][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_10);
        aec_exp_means[3][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_11);
        aec_exp_means[3][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_12);
        aec_exp_means[3][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_13);
        aec_exp_means[3][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_14);
                                                                        
        aec_exp_means[4][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_00);
        aec_exp_means[4][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_01);
        aec_exp_means[4][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_02);
        aec_exp_means[4][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_03);
        aec_exp_means[4][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_04);
    }
    else if (TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].rotate
        && TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].v_flip
        && !TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].h_flip)
    {
        aec_exp_means[0][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_00);
        aec_exp_means[0][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_01);
        aec_exp_means[0][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_02);
        aec_exp_means[0][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_03);
        aec_exp_means[0][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_04);
        
        aec_exp_means[1][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_10);
        aec_exp_means[1][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_11);
        aec_exp_means[1][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_12);
        aec_exp_means[1][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_13);
        aec_exp_means[1][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_14);
        
        aec_exp_means[2][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_20);
        aec_exp_means[2][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_21);
        aec_exp_means[2][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_22);
        aec_exp_means[2][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_23);
        aec_exp_means[2][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_24);
        
        aec_exp_means[3][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_30);
        aec_exp_means[3][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_31);
        aec_exp_means[3][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_32);
        aec_exp_means[3][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_33);
        aec_exp_means[3][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_34);
                                                                        
        aec_exp_means[4][0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_40);
        aec_exp_means[4][1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_41);
        aec_exp_means[4][2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_42);
        aec_exp_means[4][3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_43);
        aec_exp_means[4][4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_44);
    }
    else
    {
        LOGE(TAG, "%s %d Unknown rotate or flip paramters!!!\r\n", __func__, __LINE__);
		return -1;
    }

    return 0;
}

void if_vGetFaceMeanluma_hw(int32_t idx, TsmFaceBox *nirBox, uint32_t *MeanLuma)
{
    uint8_t aec_exp_means[5][5] = {0};
    unsigned int girdXmin = 0, girdYmin = 0, girdXmax = 0, girdYmax = 0;
    uint32_t in_width, in_height;
    float sum = 0.0f;
    int32_t grid_cnt = 0;
    unsigned int faceXmin = 0, faceYmin = 0, faceXmax = 0, faceYmax = 0;
    int32_t ret = 0;
    
    isp_res_map(g_ifv_flow_cfg.enResIR, &in_height, &in_width);    
    faceXmin = nirBox->xmin * in_width;
    faceYmin = nirBox->ymin * in_height;
    faceXmax = nirBox->xmax * in_width;
    faceYmax = nirBox->ymax * in_height;

    *MeanLuma = 0;
    
    if ((faceXmin < 0 || faceXmax < 0 || faceYmin < 0 || faceYmax < 0)
		|| (faceXmin == 0 && faceXmax == 0 && faceYmin == 0 && faceYmax == 0))
    {
        //LOGD(TAG, "%s %d\r\n", __func__, __LINE__);
		return;
    }

    ret = if_vGetRotateLuma(idx, aec_exp_means);
    if (ret)
    {
        return;
    }
        
    for (uint32_t y = 0; y < 5; y++)
    {
        for (uint32_t x = 0; x < 5; x++)
        {            
            girdXmin = x * in_width / 5;
            girdXmax = (x + 1) * in_width / 5;
            girdYmin = y * in_height / 5;
            girdYmax = (y + 1) * in_height / 5;

            if ((girdXmin > faceXmax)
                || (girdXmax < faceXmin)
                || (girdYmin > faceYmax)
                || (girdYmax < faceYmin))
            {
                continue;
            }
                
            grid_cnt++;
            sum += (float)((uint32_t)aec_exp_means[y][x]);
        }
    }
    
	*MeanLuma = sum / grid_cnt;
    ifv_printf(IFV_MSG_DEBUG, 
            "[ISP%d] %s %d meanLuma: %d, sum: %f, cnt: %d\r\n", 
            idx, __func__, __LINE__, *MeanLuma, sum, grid_cnt);
#if 0
    if (idx == 0)
    {
        return;
    }
    
    LOGD(TAG, "[ISP%d] %s: mean_luma: %d\n\
    [%d %d], [%d %d]\n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n",
    		idx, __FUNCTION__, *MeanLuma,
    		faceXmin, faceYmin, faceXmax, faceYmax,
            aec_exp_means[0][0],
            aec_exp_means[0][1],
            aec_exp_means[0][2],
            aec_exp_means[0][3],
            aec_exp_means[0][4],

            aec_exp_means[1][0],
            aec_exp_means[1][1],
            aec_exp_means[1][2],
            aec_exp_means[1][3],
            aec_exp_means[1][4],

            aec_exp_means[2][0],
            aec_exp_means[2][1],
            aec_exp_means[2][2],
            aec_exp_means[2][3],
            aec_exp_means[2][4],

            aec_exp_means[3][0],
            aec_exp_means[3][1],
            aec_exp_means[3][2],
            aec_exp_means[3][3],
            aec_exp_means[3][4],

            aec_exp_means[4][0],
            aec_exp_means[4][1],
            aec_exp_means[4][2],
            aec_exp_means[4][3],
            aec_exp_means[4][4]);
#endif
}

void face_meanluma_calc_ir(char *imgBuf, TsmFaceBox *nirBox, int *meanLuma)
{
    unsigned int faceXmin = 0, faceYmin = 0, faceXmax = 0, faceYmax = 0;
    uint32_t in_width, in_height;
    unsigned int idx_x = 0, idx_y = 0, offset = 0;
    unsigned long G_sum = 0;

    isp_res_map(g_ifv_flow_cfg.enResIR, &in_height, &in_width);    
    faceXmin = (nirBox->xmin + (nirBox->xmax - nirBox->xmin) * 1.0f / 4.0f) * in_width;
    faceYmin = (nirBox->ymin + (nirBox->ymax - nirBox->ymin) / 2.0f) * in_height;
    faceXmax = (nirBox->xmin + (nirBox->xmax - nirBox->xmin) * 3.0f / 4.0f) * in_width;
    faceYmax = (nirBox->ymin + (nirBox->ymax - nirBox->ymin) * 3.0f / 4.0f) * in_height;
    
    LOGD(TAG, "%s %d [%d, %d], [%d, %d]\r\n", __func__, __LINE__,
        faceXmin, faceYmin, faceXmax, faceYmax);
        
    for (idx_y = faceYmin; idx_y < faceYmax; idx_y++)
    {
        for (idx_x = faceXmin; idx_x < faceXmax; idx_x++)
        {
            G_sum += imgBuf[idx_y * in_width + idx_x];
            offset++;
        }
    }
    
    if(offset ==0){
		LOGD(TAG, "offset %d\n", offset);
		*meanLuma = 0;
	}else
	{
    	*meanLuma = G_sum / offset;
	}
    //LOGD(TAG, "%s %d %d\r\n", __func__, __LINE__, *meanLuma);
    
    return;
}

void if_vGetFaceMeanluma_sw(int32_t idx, TsmFaceBox *nirBox, int32_t nFace, uint32_t *MeanLuma, uint32_t doubleIrBufNum)
{
    // uint8_t aec_exp_means[5][5] = {0};
    // unsigned int girdXmin = 0, girdYmin = 0, girdXmax = 0, girdYmax = 0;
    uint32_t in_width, in_height;
    float sum = 0.0f;
    int32_t grid_cnt = 0;
    unsigned int faceXmin = 0, faceYmin = 0, faceXmax = 0, faceYmax = 0;
    // int32_t ret = 0;
    char *imgBuf = NULL;

    *MeanLuma = 0;

	if (nFace != 1)
	{
		printf("%s %d\n", __func__, __LINE__);
		return;
	}

	isp_res_map(g_ifv_flow_cfg.enResIR, &in_height, &in_width);    
    faceXmin = nirBox->xmin * in_width;
    faceYmin = nirBox->ymin * in_height;
    faceXmax = nirBox->xmax * in_width;
    faceYmax = nirBox->ymax * in_height;

    
    if ((faceXmin < 0 || faceXmax < 0 || faceYmin < 0 || faceYmax < 0)
		|| (faceXmin == 0 && faceXmax == 0 && faceYmin == 0 && faceYmax == 0))
    {
        //LOGD(TAG, "%s %d\r\n", __func__, __LINE__);
		return;
    }

    if (g_ifv_flow_cfg.source_ir_right)
    {
        uint32_t buffer_idx = 0;
        
        if (TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id == idx)
        {
            buffer_idx = 0;
        }
		else if (TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id == idx)
        {
			buffer_idx = 1;
		}
		
        imgBuf = (char *)iva_2ir_get_buffer(buffer_idx, doubleIrBufNum);
    }
    else
    {
        imgBuf = (char *)iva_facereco_ir_get_buffer(0, 0);
    }
        
    face_meanluma_calc_ir(imgBuf, nirBox, (int *)MeanLuma);

    ifv_printf(IFV_MSG_DEBUG, 
            "[ISP%d] %s %d meanLuma: %d, sum: %f, cnt: %d\r\n", 
            idx, __func__, __LINE__, *MeanLuma, sum, grid_cnt);
#if 0
    if (idx == 0)
    {
        return;
    }
    
    LOGD(TAG, "[ISP%d] %s: mean_luma: %d\n\
    [%d %d], [%d %d]\n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n",
    		idx, __FUNCTION__, *MeanLuma,
    		faceXmin, faceYmin, faceXmax, faceYmax,
            aec_exp_means[0][0],
            aec_exp_means[0][1],
            aec_exp_means[0][2],
            aec_exp_means[0][3],
            aec_exp_means[0][4],

            aec_exp_means[1][0],
            aec_exp_means[1][1],
            aec_exp_means[1][2],
            aec_exp_means[1][3],
            aec_exp_means[1][4],

            aec_exp_means[2][0],
            aec_exp_means[2][1],
            aec_exp_means[2][2],
            aec_exp_means[2][3],
            aec_exp_means[2][4],

            aec_exp_means[3][0],
            aec_exp_means[3][1],
            aec_exp_means[3][2],
            aec_exp_means[3][3],
            aec_exp_means[3][4],

            aec_exp_means[4][0],
            aec_exp_means[4][1],
            aec_exp_means[4][2],
            aec_exp_means[4][3],
            aec_exp_means[4][4]);
#endif
}

/*
	return: 0 does not need to recognize again
	        1 need to recognize again
*/
int checkIfRecogContinue(int32_t faceResult, int32_t faceLuma_L, int32_t faceLuma_R)
{
	int32_t faceSetpointMin = (int32_t)(FACE_AE_SENSOR_SETPOINT * 0.9);
	int32_t faceSetpointMax = (int32_t)(FACE_AE_SENSOR_SETPOINT * 1.1);
	int32_t ispSetpointMin = (int32_t)(SENSOR_SETPOINT * 0.9);
	int32_t ispSetpointMax = (int32_t)(SENSOR_SETPOINT * 1.1);
	int32_t ispLuma_L = g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id];
	//int32_t ispLuma_R = 0;
	int32_t loopCounter = g_face_ae_info.loop_counter;
	
	if (loopCounter >= IFV_RECOG_REG_LOOP_COUNT)
		return 0;

	if (FACE_RESULT_SUCCESS == faceResult)
	{
		return 0;
	}
	else if (((FACE_RESULT_LIVING_NIR_FAILED == faceResult)
		|| (FACE_RESULT_BAD_POSTURE == faceResult)
		|| (FACE_RESULT_LIVING_3D_FAILED == faceResult)
		|| (FACE_RESULT_NOT_MATCH == faceResult)))
	{
		if (((faceLuma_L <= faceSetpointMax) && (faceLuma_L >= faceSetpointMin))
			&& (((faceLuma_R <= faceSetpointMax) && (faceLuma_R >= faceSetpointMin)) || !g_ifv_flow_cfg.source_ir_right))
		{
			return 0;
		}
	}
	else if (FACE_RESULT_NO_FACE == faceResult)
	{
		if ((ispLuma_L <= ispSetpointMax) && (ispLuma_L >= ispSetpointMin))
			//|| (((ispLuma_R > ispSetpointMax) || (ispLuma_R < ispSetpointMin))))
		{
			return 0;
		}
	}

	return 1;	
}
#endif

uint8_t g_runmode_cover = false;
int checkFaceResult(TsmFaceResult *tp, uint8_t living_nir_enable, uint8_t living_3d_enable)
{
	int i = 0;
	int ret = 0;
	if(NULL == tp)
		return -1;

	if(0 == tp->nFace){
		ret = FACE_RESULT_NO_FACE;
	}
	else if(1 == tp->nFace)
	{
		for (i = 0; i < tp->nFace; i++)
	    {
			LOGD(TAG, "pose[0]:%f pose[1]:%f\n",fabs(tp->qa[i].pose[0]),fabs(tp->qa[i].pose[1]));
			if(tp->qa[i].bad_posture){
				if(tp->qa[i].bad_posture){
					ret = FACE_RESULT_BAD_POSTURE;
					LOGD(TAG, "please move your head. \n");
					break;
				}
			}
#if 0
			if(tp->qa[i].fuzzy){
				ret = FACE_RESULT_FUZZY;
				LOGD(TAG, "the current face fuzzy! \n");
				break;
			}		
#endif
			if(g_runmode_cover == true){
				if(tp->qa[i].cover){
					ret = FACE_RESULT_COVER;
					LOGD(TAG, "the current face cover!\n");
					break;
				}
			}

			if(living_nir_enable){
                LOGD(TAG, "nir score %f \n", tp->scoreNir[i]);
				if(tp->nirCheckFailed[i]){
					ret = FACE_RESULT_LIVING_NIR_FAILED;
					LOGD(TAG, "nir check failed,score %f \n", tp->scoreNir[i]);
					break;
				}
			}

//temp
#if CONFIG_DEPTH_DOUBLE_IR
            if (tp->sl3dCheckFailed[i])
            {
				ret = FACE_RESULT_LIVING_3D_FAILED;
				printf("living 3d check failed\n");
            }
#endif
            
#if LIVE_3D_ENABLE
			if(tp->sl3dCheckFailed[i] && living_3d_enable){
				ret = FACE_RESULT_LIVING_3D_FAILED;
				LOGD(TAG, "living 3d check failed,score %f \n", tp->scoreLive3D[i]);
			}
#else
			if(!living_3d_flag && living_3d_enable){
				ret = FACE_RESULT_LIVING_3D_FAILED;
				LOGD(TAG, "luma 3d check failed \n");
				break;
			}
#endif
			break;
		}

		if (!g_ifv_flow_cfg.register_pic)
		{
        //if (g_ifv_flow_cfg.face_ae_ir)
        //    face_ae_ir(tp);
			
			if (g_ifv_flow_cfg.save_ae_enable)
			{
				cis_aelock_save(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
			}
		}
	}
	else
	{
		ret = FACE_RESULT_FACE_MORE;
		LOGD(TAG, "faceNum: %d.\n", tp->nFace);
		LOGD(TAG, "Warning: faces more than one! \n");	
	}

	return ret;
}

#ifdef BCTC_TEST
int checkBctcFaceResult(TsmFaceResult *tp, uint8_t living_nir_enable, uint8_t living_3d_enable, uint32_t *uartRet)
{
	int i = 0;
	int ret = 0;
	if(NULL == tp)
		return -1;

	if(0 == tp->nFace){
		ret = FACE_RESULT_NO_FACE;
	}
	else if(1 == tp->nFace)
	{
		for (i = 0; i < tp->nFace; i++)
	    {
			if(tp->qa[i].fuzzy){
				ret = FACE_RESULT_FUZZY;
				LOGD(TAG, "the current face fuzzy! \n");
				*uartRet |= 1 << BCTC_QA_ERROR_FUZZY;
			}		

			if(g_runmode_cover == true){
				if(tp->qa[i].cover){
					ret = FACE_RESULT_COVER;
					LOGD(TAG, "the current face cover!\n");
				*uartRet |= 1 << BCTC_QA_ERROR_COVER;
				}
			}

			if((tp->qa[i].pose[0] > 20) || (tp->qa[i].pose[0] < -20) || (tp->qa[i].pose[1] > 20) 
					||(tp->qa[i].pose[1] < -20) || (tp->qa[i].pose[2] > 20) || (tp->qa[i].pose[2] < -20)){
				ret = FACE_RESULT_NOT_MATCH;
				LOGD(TAG, "the current face row:%d, pitch:%d,yaw:%d > |20|!\n", tp->qa[i].pose[0], tp->qa[i].pose[1], tp->qa[i].pose[2]);
				*uartRet |= 1 << BCTC_QA_ERROR_ANGLE;
			}
		}

		if (!g_ifv_flow_cfg.register_pic)
		{
        //if (g_ifv_flow_cfg.face_ae_ir)
        //    face_ae_ir(tp);
			
			if (g_ifv_flow_cfg.save_ae_enable)
			{
				cis_aelock_save(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
			}
		}
	}
	else
	{
		ret = FACE_RESULT_FACE_MORE;
		LOGD(TAG, "faceNum: %d.\n", tp->nFace);
		LOGE(TAG, "Warning: faces more than one! \n");	
		*uartRet |= 1 << BCTC_QA_ERROR_MULTIPLE_FACE;	
	}

	return ret;
}
#endif

uint8_t g_aieresult_print = 0;
void if_v_Recognize_ir_event_callback(int event, void *pData)
{
	int ret = 0;
	// uint32_t i = 0;
	// TsmFaceBox *pBox = NULL;
	// int max_score_id = 0;
	// float max_score = 0;
	// float matchScore = 0;
	// short *vec = NULL;
	// Match *match = NULL;	
	TsmFaceResult *tp = NULL;
	CmdRecognizeCBinfo_S userInfo;
	// uint32_t 	recoStatus=0;
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	uint32_t meanLuma_L = 0;

	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);

	tp = (TsmFaceResult *)pData;

	if(1 == register_ir_flag)
	{
		int32_t ff_id = 0x7fffffff;
		CmdRegisterCBinfo_S userRegisterInfo;
		TsmFaceFeatrue *pFeature = &tp->feature;
        TsmFaceFeatrue *pMaskFeature = &tp->mask_feature;
		ret = checkFaceResult(tp,register_ir_nir_living_flag,0);
        if (g_ifv_flow_cfg.face_ae_ir)
        {
            if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
                            tp->nirBox,
							tp->nirFace, 
                            &meanLuma_L,
							0);
        }
		//if((0 == ret)&&(meanLuma_L < g_ifv_flow_cfg.ir_faceAE_param.luma_max))
		if(0 == ret)
	    {
            int temp_id=-1;

            if(g_register_once_one_person){
		        temp_id = getRecoMaxSimilarityId(tp, faceFeature, 0);
                
            }

			if(temp_id == -1){
				if(1 == g_multiAngleRegister){
					userRegisterInfo.result = FACE_RESULT_SUCCESS;
					g_multiAngleRegister = 0;
				}
				else{
	        		ff_id = tsm_ff_add(pFeature->vector + pFeature->len * 0, pMaskFeature->vector + pMaskFeature->len * 0);
				//update feature need before uart ack : by lfcui
				//aie_feature_update(FACE_FEATURE_MAX_NUM,FACE_FEATURE_ADR);
	        		if (ff_id >= 0)
	        		{
	            		ifv_printf(IFV_MSG_ERROR, "Success to add face feature with id %d\r\n", ff_id);
						userRegisterInfo.result = 0;
						userRegisterInfo.id = ff_id;

						if(0 == enroll_from_uart_busy_flag)
						{
						//call user register cb function,
							userCmdArrayCB[0].pfuncmd(&userRegisterInfo);
						}
						else if(1 == enroll_from_uart_busy_flag)
						{
							registerFromUartAck(0,ff_id);
						}
					}
	    		}
			}
			else
			{
				printf("register already.\n");
				userRegisterInfo.result = FACE_RESULT_REPEAT;
				userRegisterInfo.id = 0xffffffff;
                userCmdArrayCB[0].pfuncmd(&userRegisterInfo);
			}	
		}
		else
		{
			if(0 == enroll_from_uart_busy_flag)
			{
				userRegisterInfo.result = ret;
				userRegisterInfo.id = 0xffffffff;
				//call user register cb function,
				userCmdArrayCB[0].pfuncmd(&userRegisterInfo);
			}
			else if(1 == enroll_from_uart_busy_flag)	
			{
				registerFromUartAck(1,0xfffffffe);
				//enroll_from_uart_busy_flag = 0;
			}			
		}

		register_ir_flag = 0;
	    ifv_stop_time = aos_now_ms();
	    //LOGD(TAG, "@OUT reco=%d\n", ifv_stop_time);
	    enroll_or_recognize_busy_flag = 0;

		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;

        printf("%s %d loop: %d\r\n", __func__, __LINE__, g_face_ae_info.loop_counter);
        
        // if (ret != FACE_RESULT_NO_FACE)
        // {
        //     if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
        //                 tp->nirBox, 
        //                 &meanLuma_L);
        // }
        
        printf("%s %d [%d] isp luma: %d, face luma: %d\r\n", 
                __func__, __LINE__,ret, 
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id],
                meanLuma_L);
		// if (
		// 	//(meanLuma_L && ((meanLuma_L > g_ifv_flow_cfg.ir_faceAE_param.luma_max) 
        //     //     || (meanLuma < g_ifv_flow_cfg.ir_faceAE_param.luma_min) ))
        //     ((FACE_RESULT_LIVING_NIR_FAILED == ret)
        //     || (FACE_RESULT_BAD_POSTURE == ret)
        //     || (FACE_RESULT_NO_FACE == ret))
        //     && g_face_ae_info.loop_counter < IFV_RECOG_REG_LOOP_COUNT)
		if (1 == checkIfRecogContinue(ret, meanLuma_L, 0))
        {
            // ifv_msg_pkg_t msg;
            //printf("%s %d, result: %d\r\n", __func__, __LINE__, ret);
            //memcpy(&g_face_ae_info.nirBox, tp->nirBox, sizeof(TsmFaceBox));
            //g_face_ae_info.nir_box_ready = true;
            g_face_ae_info.loop_counter++;
            if (g_ifv_flow_cfg.face_ae_ir
                && ret != FACE_RESULT_NO_FACE)
            {
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id], tp->nirBox, sizeof(TsmFaceBox));
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = tp->nFace;
				g_face_ae_info.inProcess = 1;
            }
			else
			{
				g_face_ae_info.inProcess = 0;
			}
            memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
            memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);
            // msg.cmd = APP2IFV_REGISTER_CMD;
            // ifv_post_msg(msg);
            return;
        }

		if_vFace_ae_clean();

		//set expo init mode
		// scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
		// if (((SENSOR_EXPO_INDOOR == lumaCfg.scene) || (SENSOR_EXPO_OUTDOOR == lumaCfg.scene))
		// 	&& g_scenario_type != lumaCfg.scene)
		// {
		// 	g_scenario_type = lumaCfg.scene;
		// 	ret = aos_kv_set(AEC_KV_EXPO_INIT_MODE, &g_scenario_type, sizeof(g_scenario_type), 1);
		// 	if (ret != 0) 
		// 		ifv_printf(IFV_MSG_ERROR, "Failed to save expo init mode [%d]\n", ret);
		// 	else
		// 		ifv_printf(IFV_MSG_DEBUG, "Successful to save expo init mode [%d]\n", g_scenario_type);
		// }
        return;
	}
	else
	{
		ret = checkFaceResult(tp, 
                        g_ifv_flow_cfg.live_nir_enable,
                        g_ifv_flow_cfg.source_spk);
		if(0 == ret)
		{
			uint8_t *faceFeature_temp = NULL;

			if(tp->qa[0].mask)
			{
			    faceFeature_temp = faceMaskFeature;
			}
            else
            {
			    faceFeature_temp = faceFeature;
            }
			userInfo.id = getRecoMaxSimilarityId(tp, faceFeature_temp, 0); //suport only one bigger face
			if(userInfo.id == -1)
			{
				userInfo.result = FACE_RESULT_NOT_MATCH;
				userInfo.id = 0xffffffff;
			}
			else
			{
				userInfo.result = FACE_RESULT_SUCCESS;
				LOGD(TAG, "recognize id: %d \n", userInfo.id);
				if(g_aieresult_print == false)
					printAIResult(tp);
				enroll_or_recognize_busy_flag = 0;
			}
			userCmdArrayCB[1].pfuncmd(&userInfo);			
		}
		else
		{
#if 0
            if (g_ifv_flow_cfg.face_ae_ir
				&& (FACE_RESULT_LIVING_NIR_FAILED == ret)
                && !g_face_ae_info.face_ae_done)
            {
    			ifv_msg_pkg_t msg;
        		msg.cmd = APP2IFV_RECOGNIZE_CMD;
        		ifv_post_msg(msg);
                return;
            }
#endif                
			userInfo.result = ret;
			userInfo.id = 0xffffffff;
			userCmdArrayCB[1].pfuncmd(&userInfo);
		}
        if ((g_ifv_flow_cfg.face_ae_ir) && (ret != FACE_RESULT_NO_FACE))
        {
            if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
                        tp->nirBox,
						tp->nirFace, 
                        &meanLuma_L,
						0);
        }
        printf("%s %d [%d] isp luma: %d, face luma: %d\r\n", 
                __func__, __LINE__,ret, 
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id],
                meanLuma_L);
		// if ((
		// 	//((meanLuma_L && ((meanLuma_L > g_ifv_flow_cfg.ir_faceAE_param.luma_max) 
        //     //     || (meanLuma < g_ifv_flow_cfg.ir_faceAE_param.luma_min) ))
        //     (FACE_RESULT_LIVING_NIR_FAILED == ret)
        //     || (FACE_RESULT_BAD_POSTURE == ret)
        //     || (FACE_RESULT_NO_FACE == ret)
        //     || (FACE_RESULT_NOT_MATCH == ret))
        //     && g_face_ae_info.loop_counter < IFV_RECOG_REG_LOOP_COUNT)
		if (1 == checkIfRecogContinue(ret, meanLuma_L, 0))
        {
            //ifv_msg_pkg_t msg;
            //printf("%s %d, result: %d\r\n", __func__, __LINE__, ret);
            //memcpy(&g_face_ae_info.nirBox, tp->nirBox, sizeof(TsmFaceBox));
            //g_face_ae_info.nir_box_ready = true;
            g_face_ae_info.loop_counter++;
            if (g_ifv_flow_cfg.face_ae_ir
                && ret != FACE_RESULT_NO_FACE)
            {
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id], tp->nirBox, sizeof(TsmFaceBox));
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = tp->nFace;
				g_face_ae_info.inProcess = 1;
            }
			else
			{
				g_face_ae_info.inProcess = 0;
			}
            memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
            memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);
            //msg.cmd = APP2IFV_RECOGNIZE_CMD;
            //ifv_post_msg(msg);
            return;
        }

		if_vFace_ae_clean();

		//set expo init mode
		// scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
		// if (((SENSOR_EXPO_INDOOR == lumaCfg.scene) || (SENSOR_EXPO_OUTDOOR == lumaCfg.scene))
		// 	&& g_scenario_type != lumaCfg.scene)
		// {
		// 	g_scenario_type = lumaCfg.scene;
		// 	ret = aos_kv_set(AEC_KV_EXPO_INIT_MODE, &g_scenario_type, sizeof(g_scenario_type), 1);
		// 	if (ret != 0) 
		// 		ifv_printf(IFV_MSG_ERROR, "Failed to save expo init mode [%d]\n", ret);
		// 	else
		// 		ifv_printf(IFV_MSG_DEBUG, "Successful to save expo init mode [%d]\n", g_scenario_type);
		// }
		g_usbRecogState=1;
#if 1	//debug
	if(g_aieresult_print == true)	
		printAIResult(tp);
#endif

	}

	ifv_printf(IFV_MSG_INFO," %s recog complete\r\n", __func__);
}

#define RECOGNIZE_FAILED_PATH   FS_ROOT_PATH"/failed"

int g_irRecognizeFailedCount=0;
void if_vSaveRecognizeFailedToFs(int mask_type, int fType, float liveScore)
{
    uint8_t filePath[128] = {0};
    // unsigned char *pJpegBuffer = NULL;
    // unsigned long outSize = 0;
    aos_dir_t *dp = NULL;
    int fd = -1;
    int ret = 0;

    if(g_ifVsaveIrEnable){
         dp = (aos_dir_t *)aos_opendir(RECOGNIZE_FAILED_PATH);
         if (!dp) {
             ret = aos_mkdir(RECOGNIZE_FAILED_PATH);
         } else {
                 LOGD(TAG, "%s exist\n",__func__);
         }

        sprintf((char *)filePath, "%s/IR_failed_%x%x_mask_%d_match_%d_live_%f_reco_%f_%d.raw", 
                RECOGNIZE_FAILED_PATH, ifvRandomKey[0],ifvRandomKey[1],mask_type,fType,liveScore,g_RecoMaxScore,g_irRecognizeFailedCount++);
        
        fd = aos_open((char *)filePath, O_RDWR | O_CREAT | O_TRUNC);
        if (fd < 0) {
            LOGE(TAG, "%s aos_open err.\n",__func__);
            goto exit;
        }

        if(aos_write(fd, (char *)iva_facereco_ir_get_buffer(0, 0), IFV_IR_PIC_SIZE) != IFV_IR_PIC_SIZE){
            LOGD(TAG, "aos_write err.\n");
            goto exit;
        }
     }
    exit:
    if(fd >= 0){
        aos_close(fd);
    }
    if(dp){
        aos_closedir(dp);
    }
}


int ifv_facerecofailedpro(TsmFaceResult *result, CmdRecognizeCBinfo_S* userInfo)
{
	static int recognize_count = 0;
	if(userInfo->result != FACE_RESULT_SUCCESS)
	{
		recognize_count++;
		if(recognize_count<3){
			if(g_aieresult_print)
			{
				printAIResult(result);
			}
			memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
        	//qw_isp_ae_unlock(ISP_0);
			//qw_isp_ae_unlock(ISP_1);
			ifv_msg_pkg_t msg;
    		msg.cmd = APP2IFV_RECOGNIZE_CMD;
    		ifv_post_msg(msg);
		} 
		else
		{
			recognizeResultAck(userInfo->result, userInfo->id);
			recognize_count = 0;
#if 1	//debug
			printAIResult(result);
#endif
			//memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
		}	
	}
	else //success
	{
		recognizeResultAck(userInfo->result, userInfo->id);
		recognize_count = 0;
#if 1	//debug
		printAIResult(result);
#endif
	}
		
	return 0;
}


void if_v_Recognize_double_ir_event_callback(int event, void *pData)
{
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	ifv_printf(IFV_MSG_INFO,"===== %s pData 0x%x=====\r\n", __func__, pData);

	int ret = 0;
	int32_t ff_id = 0x7fffffff;
	TsmFaceResult *tp = (TsmFaceResult *)pData;
	TsmFaceFeatrue *pFeature = &tp->feature;
    TsmFaceFeatrue *pMaskFeature = &tp->mask_feature;
	// TsmFaceBox *pBox = NULL;
	CmdRecognizeCBinfo_S userInfo;
    uint32_t meanLuma_L = 0, meanLuma_R = 0;

	userInfo.flag = 0;

	if(IFV_REGISTER_MODE_PIC_IR_RAW == if_vGetRegisterMode())
	{

		tp = (TsmFaceResult *)pData;

		ifv_printf(IFV_MSG_INFO, "face num : %d \n",tp->nFace);
		ret = checkFaceResult(tp,1,0);
		if(0 == ret)
		{
	        pFeature = &((TsmFaceResult *)pData)->feature;
	        pMaskFeature = &((TsmFaceResult *)pData)->mask_feature;
	        ff_id = tsm_ff_add(pFeature->vector + pFeature->len * 0,pMaskFeature->vector + pMaskFeature->len * 0 );
	        ifv_printf(IFV_MSG_INFO, "tsm_ff_add : %lld \n",aos_now_ms() - ifv_stop_time);
			if (ff_id >= 0)
			{
				userInfo.result = FACE_RESULT_SUCCESS;
				userInfo.id = ff_id;
	            ifv_printf(IFV_MSG_ERROR, "Success to add face feature with id %d\r\n", ff_id);
				registerFromUartAck(0,ff_id);
			}
		}
		else
		{
			
			userInfo.result = ret;
			userInfo.id = 0xffffffff;
			registerFromUartAck(1,0xfffffffe);
		}

		if_vSetRegisterMode(IFV_REGISTER_MODE_NONE);
		
		memcpy(userInfo.pose, tp->qa[0].pose, sizeof(userInfo.pose));
		userCmdArrayCB[3].pfuncmd(&userInfo);
		return;
	}else if(g_ifv_flow_cfg.register_pic)
	{
		tp = (TsmFaceResult *)pData;

		ifv_printf(IFV_MSG_INFO, "face num : %d \n",tp->nFace);

#ifdef BCTC_TEST
		int32_t uartRet = 0;
		ret = checkBctcFaceResult(tp,0,0,&uartRet);
		registerFromUartAck(ret,uartRet);
		g_ifv_flow_cfg.register_pic = 0;
		enroll_from_uart_busy_flag = 0;
		enroll_or_recognize_busy_flag = 0;
		return;
#endif

		ret = checkFaceResult(tp,0,0);
		if(0 == ret)
		{
	        pFeature = &((TsmFaceResult *)pData)->feature;
	        pMaskFeature = &((TsmFaceResult *)pData)->mask_feature;
	        ff_id = tsm_ff_add(pFeature->vector + pFeature->len * 0,pMaskFeature->vector + pMaskFeature->len * 0 );
	        ifv_printf(IFV_MSG_INFO, "tsm_ff_add : %lld \n",aos_now_ms() - ifv_stop_time);
			if (ff_id >= 0)
			{
	            ifv_printf(IFV_MSG_ERROR, "Success to add face feature with id %d\r\n", ff_id);
				registerFromUartAck(0,ff_id);
			}
		}
		else
		{
			registerFromUartAck(1,0xfffffffe);
		}

		g_ifv_flow_cfg.register_pic = 0;
		enroll_from_uart_busy_flag = 0;
		enroll_or_recognize_busy_flag = 0;
		return;
	}

	if((g_variable_cfg.g_calibration_flag) || (g_variable_cfg.g_calib_estimate_flag))
	{
		tsmTRP_Sl3dCfg_t sl3d_cfg_newc =
		{
			0,1,
			{640,360,0,TRP_SAD_WIN_SIZE_13,true},
			{80,80*13*13},
			{640,360,NULL,NULL,NULL,NULL,NULL},
			{0,40,8,0},
			{1,20.0f},
			{TRP_DISP_RANGE_NEG_32_8160,4000},
			{-1.0f, 18.0, FOCAL_LENGTH_3D, 0},
			TRP_SL3D_DEBUG_MAX_MODULE,
		};

		ifv_msg_pkg_t msg;
		static int calib_ok = 0;

		memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
		
		ret = checkFaceResult(tp,register_ir_nir_living_flag,0);
		
		//snap next pic
		printf("%s %d ae loop: %d\r\n", __func__, __LINE__, g_face_ae_info.loop_counter);

		printf("%s %d calib loop: %d\r\n", __func__, __LINE__, g_variable_cfg.g_calibration_loop_count);

        if ((g_ifv_flow_cfg.face_ae_ir) && (ret != FACE_RESULT_NO_FACE))
        {
        	if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
                            tp->box,
							tp->nFace, 
                            &meanLuma_L,
							0);
            if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, 
                            tp->nirBox,
							tp->nirFace, 
                            &meanLuma_R,
							0);
        }
        
        printf("%s %d isp luma: %d:%d, face luma: %d:%d\r\n", 
                __func__, __LINE__, 
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id],
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id],
                meanLuma_L,
                meanLuma_R);
		// if ((
		// 	// (meanLuma_L && ((meanLuma_L > g_ifv_flow_cfg.ir_faceAE_param.luma_max[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id])))
        //     // || (meanLuma_R && ((meanLuma_R > g_ifv_flow_cfg.ir_faceAE_param.luma_max[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id])))
        //     // || (meanLuma_L && ((meanLuma_L < g_ifv_flow_cfg.ir_faceAE_param.luma_min[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id])))
        //     // || (meanLuma_R && ((meanLuma_R < g_ifv_flow_cfg.ir_faceAE_param.luma_min[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id])))
        //     (FACE_RESULT_LIVING_NIR_FAILED == ret)
        //     || (FACE_RESULT_BAD_POSTURE == ret)
        //     || (FACE_RESULT_NO_FACE == ret)
		// 	|| (FACE_RESULT_LIVING_3D_FAILED == ret)
        //     || (FACE_RESULT_NOT_MATCH == ret))
        //     && g_face_ae_info.loop_counter < IFV_RECOG_REG_LOOP_COUNT)
		if (1 == checkIfRecogContinue(ret, meanLuma_L, meanLuma_R))
        {
            //printf("%s %d, result: %d\r\n", __func__, __LINE__, ret);
            //memcpy(&g_face_ae_info.nirBox, tp->nirBox, sizeof(TsmFaceBox));
            //g_face_ae_info.nir_box_ready = true;

			g_face_ae_info.loop_counter++;
           
            if (g_ifv_flow_cfg.face_ae_ir
                && ret != FACE_RESULT_NO_FACE)
            {
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id], tp->nirBox, sizeof(TsmFaceBox));
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id], tp->box, sizeof(TsmFaceBox));
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = tp->nirFace;
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = tp->nFace;
				g_face_ae_info.inProcess = 1;
            }
			else
			{
				g_face_ae_info.inProcess = 0;
			}
            memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
            memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);

			if(g_variable_cfg.g_calibration_flag){
				msg.cmd = APP2IFV_CALIBRATION_CMD;
			}else if(g_variable_cfg.g_calib_estimate_flag){
				msg.cmd = APP2IFV_CALIB_ESTIMATE_CMD;
			}
            
            ifv_post_msg(msg);
            return;
        }
		
		if(0 == ret) {
			userInfo.result = 0;
			if(g_variable_cfg.g_calib_estimate_flag)
				calib_ok++;
		}
		else {
			userInfo.result = 1;
		}

		if((g_variable_cfg.g_calibration_loop_count == IFV_DOUBLE_IR_CALIB_LOOP_COUNT) && (g_variable_cfg.g_calib_estimate_flag))
		{
			if((calib_ok > 0)){
				printf("loop over,save calib para \n");
				calib_ok = 0;
				//save
				if_vCalibration_save();
				userInfo.result = 0;

				//sl3d_cfg_newc.rectify.leftFXY = y2;
				sl3d_cfg_newc.rectify.rightFXY = g_variable_cfg.ir2_dep_y2;
				//sl3d_cfg_newc.rectify.leftXY = x2;
				sl3d_cfg_newc.rectify.rightXY = g_variable_cfg.ir2_dep_x2;
				sl3d_cfg_newc.rectify.weight = g_variable_cfg.ir2_dep_tab2d;
			}
			
			ret = TSM_ALGO_InitSl3dDepth_doubleIR(&sl3d_cfg_newc);
			if (ret != 0) {
				LOGE("iva", "sl3d init:%d\n", ret);
			}

			CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, SENSOR_SETPOINT);
			CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, SENSOR_SETPOINT);

			g_variable_cfg.g_calibration_flag = 0;
			g_variable_cfg.g_calib_estimate_flag = 0;
		}	

		userInfo.tp = NULL;
		userCmdArrayCB[7].pfuncmd(&userInfo);

		if_vFace_ae_clean();

		//set expo init mode
		// scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
		// if (((SENSOR_EXPO_INDOOR == lumaCfg.scene) || (SENSOR_EXPO_OUTDOOR == lumaCfg.scene))
		// 	&& g_scenario_type != lumaCfg.scene)
		// {
		// 	g_scenario_type = lumaCfg.scene;
		// 	ret = aos_kv_set(AEC_KV_EXPO_INIT_MODE, &g_scenario_type, sizeof(g_scenario_type), 1);
		// 	if (ret != 0) 
		// 		ifv_printf(IFV_MSG_ERROR, "Failed to save expo init mode [%d]\n", ret);
		// 	else
		// 		ifv_printf(IFV_MSG_DEBUG, "Successful to save expo init mode [%d]\n", g_scenario_type);
		// }

		// CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, SENSOR_SETPOINT);
		// CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, SENSOR_SETPOINT);

		enroll_or_recognize_busy_flag = 0;
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
		memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);

		g_usbRecogState=1;
		return;
	}
	else if(1 == register_ir_flag)
	{
		ret = checkFaceResult(tp,register_ir_nir_living_flag,0);
		if(0 == ret)
		{
		    int temp_id=-1;

            if(g_register_once_one_person){
		        temp_id = getRecoMaxSimilarityId(tp, faceFeature, 0);
            }

			if(temp_id == -1){
				if(1 == g_multiAngleRegister){
					userInfo.result = FACE_RESULT_SUCCESS;
					g_multiAngleRegister = 0;
					ifv_printf(IFV_MSG_ERROR, "%s:%d\r\n", __func__, __LINE__);
				}
				else{
					ff_id = tsm_ff_add(pFeature->vector + pFeature->len * 0, pMaskFeature->vector + pMaskFeature->len * 0);
					if (ff_id >= 0)
					{
						ifv_printf(IFV_MSG_ERROR, "Success to add face feature with id %d\r\n", ff_id);
						if(0 == enroll_from_uart_busy_flag)
						{
							//registerResultAck(0,ff_id);
							userInfo.result = FACE_RESULT_SUCCESS;
							userInfo.id = ff_id;
						}
						else if(1 == enroll_from_uart_busy_flag)
						{
							registerFromUartAck(0,ff_id);
						}
					}
				}
			}else{
				LOGD(TAG, "register already.\n");
				userInfo.result = FACE_RESULT_REPEAT;
				if(1 == g_multiAngleRegister){
					g_multiAngleRegister = 0;
					ifv_printf(IFV_MSG_ERROR, "%s:%d\r\n", __func__, __LINE__);
				}
				else
					userInfo.id = 0xffffffff;
			}  
		}
		else
		{
			if(0 == enroll_from_uart_busy_flag)
			{
				//registerResultAck(ret,0xffffffff);
                
                userInfo.result = ret;
                userInfo.id = 0xffffffff;
			}
			else if(1 == enroll_from_uart_busy_flag)	
			{
				registerFromUartAck(1,0xfffffffe);
				//enroll_from_uart_busy_flag = 0;
			}
            memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
		}

		register_ir_flag = 0;
		ifv_stop_time = aos_now_ms();

		enroll_or_recognize_busy_flag = 0;
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;


        LOGD(TAG, "%s %d loop: %d\r\n", __func__, __LINE__, g_face_ae_info.loop_counter);
        
        if ((g_ifv_flow_cfg.face_ae_ir) && (ret != FACE_RESULT_NO_FACE))
        {
        	if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
                            tp->box,
							tp->nFace, 
                            &meanLuma_L,
							0);
            if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, 
                            tp->nirBox,
							tp->nirFace, 
                            &meanLuma_R,
							0);
        }

        
        LOGD(TAG, "%s %d isp luma: %d:%d, face luma: %d:%d\r\n", 
                __func__, __LINE__, 
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id],
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id],
                meanLuma_L,
                meanLuma_R);
//		if (((meanLuma_L && ((meanLuma_L > g_ifv_flow_cfg.ir_faceAE_param.luma_max)
//                /* || (meanLuma < g_ifv_flow_cfg.ir_faceAE_param.luma_min) */))
//            || (meanLuma_R && ((meanLuma_R > g_ifv_flow_cfg.ir_faceAE_param.luma_max)
//                /* || (meanLuma < g_ifv_flow_cfg.ir_faceAE_param.luma_min) */))
//            || (FACE_RESULT_LIVING_NIR_FAILED == ret)
//            || (FACE_RESULT_BAD_POSTURE == ret)
//            || (FACE_RESULT_NO_FACE == ret)
//            || (FACE_RESULT_NOT_MATCH == ret))
//            && g_face_ae_info.loop_counter < IFV_RECOG_REG_LOOP_COUNT)
		// if(((FACE_RESULT_LIVING_NIR_FAILED == ret)||(FACE_RESULT_BAD_POSTURE == ret)||(FACE_RESULT_NO_FACE == ret)||(FACE_RESULT_NOT_MATCH == ret))
		// 	&&(g_face_ae_info.loop_counter < IFV_RECOG_REG_LOOP_COUNT))
		if (1 == checkIfRecogContinue(ret, meanLuma_L, meanLuma_R))
        {
            ifv_msg_pkg_t msg;
            //LOGD(TAG, "%s %d, result: %d\r\n", __func__, __LINE__, ret);
            //memcpy(&g_face_ae_info.nirBox, tp->nirBox, sizeof(TsmFaceBox));
            //g_face_ae_info.nir_box_ready = true;
            g_face_ae_info.loop_counter++;
            if (g_ifv_flow_cfg.face_ae_ir
                && ret != FACE_RESULT_NO_FACE)
            {
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id], tp->nirBox, sizeof(TsmFaceBox));
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id], tp->box, sizeof(TsmFaceBox));
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = tp->nirFace;
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = tp->nFace;
				g_face_ae_info.inProcess = 1;
            }
			else
			{
				g_face_ae_info.inProcess = 0;
			}
            memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
            memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);
            msg.cmd = APP2IFV_REGISTER_CMD;
            ifv_post_msg(msg);
            return;
        }

		if_vFace_ae_clean();

		//set expo init mode
		// scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
		// if (((SENSOR_EXPO_INDOOR == lumaCfg.scene) || (SENSOR_EXPO_OUTDOOR == lumaCfg.scene))
		// 	&& g_scenario_type != lumaCfg.scene)
		// {
		// 	g_scenario_type = lumaCfg.scene;
		// 	ret = aos_kv_set(AEC_KV_EXPO_INIT_MODE, &g_scenario_type, sizeof(g_scenario_type), 1);
		// 	if (ret != 0) 
		// 		ifv_printf(IFV_MSG_ERROR, "Failed to save expo init mode [%d]\n", ret);
		// 	else
		// 		ifv_printf(IFV_MSG_DEBUG, "Successful to save expo init mode [%d]\n", g_scenario_type);
		// }

		userInfo.flag = 1;
		userInfo.tp = pData;
		
        userCmdArrayCB[3].pfuncmd(&userInfo);
        return;
        
	}
	else if(1 == aie_ir_detect_enable)
	{
		userInfo.result=tp->nFace;
		enroll_or_recognize_busy_flag = 0;
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
	}
	else 
	{
		ret = checkFaceResult(tp,1,0);
		if(0 == ret)
		{
			userInfo.id = getRecoMaxSimilarityId(tp, faceFeature, 0); //suport only one biger face
			if(userInfo.id == -1)
			{
				memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
				userInfo.result = FACE_RESULT_NOT_MATCH;
				userInfo.id = 0xffffffff;
			}
			else
			{
				userInfo.result = FACE_RESULT_SUCCESS;
				LOGD(TAG, "recognize id: %d \n", userInfo.id);
			}
		}
		else
		{	
			userInfo.result = ret;
			userInfo.id = 0xffffffff;
			//LOGD(TAG, "Clean ConverGent  %d:%d:%d\n", g_irSensorConvergent[0], g_irSensorConvergent[1], g_irSensorConvergent[2]);      
		}

		enroll_or_recognize_busy_flag = 0;
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
		memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
#if 0
		//recognizeResultAck(userInfo.result, userInfo.id);
		//memset(g_irSensorConvergent, 0, sizeof(uint32_t) * ISP_NUM);
#if 0	//debug
		printAIResult(tp);
#endif	
#else
		//ifv_facerecofailedpro(tp, &userInfo);	
#endif
		userInfo.flag = 2;
#if 0
        if (g_ifv_flow_cfg.face_ae_ir)
        {
            if (FACE_RESULT_NO_FACE == ret)
            {
                memset(&g_face_ae_info.nirBox, 0x00, sizeof(TsmFaceBox));
            }
            else
            {
                memcpy(&g_face_ae_info.nirBox, tp->nirBox, sizeof(TsmFaceBox));
            }
            
            ret = aos_kv_set(AEC_KV_FACE_XY, &g_face_ae_info.nirBox, sizeof(TsmFaceBox), 1);
            if (ret != 0) 
            {
                ifv_printf(IFV_MSG_ERROR, "Failed to save face coordinate\n");
            }
            else
            {
                ifv_printf(IFV_MSG_ERROR, "Successful to save face coordinate [%f, %f], [%f, %f]\n", 
                    g_face_ae_info.nirBox.xmin,
                    g_face_ae_info.nirBox.ymin,
                    g_face_ae_info.nirBox.xmax,
                    g_face_ae_info.nirBox.ymax);
            }
        }
#endif
        LOGD(TAG, "%s %d loop: %d\r\n", __func__, __LINE__, g_face_ae_info.loop_counter);

        if ((g_ifv_flow_cfg.face_ae_ir) && (ret != FACE_RESULT_NO_FACE))
        {
            if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
                        tp->box,
						tp->nFace, 
                        &meanLuma_L,
						0);
            if_vGetFaceMeanluma_sw(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, 
                        tp->nirBox,
						tp->nirFace, 
                        &meanLuma_R,
						0);
        }
        
        LOGD(TAG, "%s %d isp luma: %d:%d, face luma: %d:%d\r\n", 
                __func__, __LINE__, 
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id],
                g_face_ae_info.meanLuma_isp[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id],
                meanLuma_L,
                meanLuma_R);
        
		// if (((meanLuma_L && ((meanLuma_L > g_ifv_flow_cfg.ir_faceAE_param.luma_max[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id])))
        //     || (meanLuma_R && ((meanLuma_R > g_ifv_flow_cfg.ir_faceAE_param.luma_max[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id])))
        //     || (meanLuma_L && ((meanLuma_L < g_ifv_flow_cfg.ir_faceAE_param.luma_min[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id])))
        //     || (meanLuma_R && ((meanLuma_R < g_ifv_flow_cfg.ir_faceAE_param.luma_min[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id])))
            // if (( (FACE_RESULT_LIVING_NIR_FAILED == ret)
            // || (FACE_RESULT_BAD_POSTURE == ret)
            // || (FACE_RESULT_NO_FACE == ret)
			// || (FACE_RESULT_LIVING_3D_FAILED == ret)
            // || (FACE_RESULT_NOT_MATCH == ret))
            // && g_face_ae_info.loop_counter < IFV_RECOG_REG_LOOP_COUNT)

		if (1 == checkIfRecogContinue(ret, meanLuma_L, meanLuma_R))		
        {
            ifv_msg_pkg_t msg;
            //LOGD(TAG, "%s %d, result: %d\r\n", __func__, __LINE__, ret);
            //memcpy(&g_face_ae_info.nirBox, tp->nirBox, sizeof(TsmFaceBox));
            //g_face_ae_info.nir_box_ready = true;
            g_face_ae_info.loop_counter++;
            if (g_ifv_flow_cfg.face_ae_ir
                && ret != FACE_RESULT_NO_FACE)
            {
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id], tp->nirBox, sizeof(TsmFaceBox));
                memcpy(&g_face_ae_info.nirBox[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id], tp->box, sizeof(TsmFaceBox));
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = tp->nirFace;
				g_face_ae_info.nirFace[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = tp->nFace;
				g_face_ae_info.inProcess = 1;
            }
			else
			{
				g_face_ae_info.inProcess = 0;
			}
            memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
            memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);
            msg.cmd = APP2IFV_RECOGNIZE_CMD;
            ifv_post_msg(msg);
            return;
        }

		if_vFace_ae_clean();

		//set expo init mode
		// scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
		// if (((SENSOR_EXPO_INDOOR == lumaCfg.scene) || (SENSOR_EXPO_OUTDOOR == lumaCfg.scene))
		// 	&& g_scenario_type != lumaCfg.scene)
		// {
		// 	g_scenario_type = lumaCfg.scene;
		// 	ret = aos_kv_set(AEC_KV_EXPO_INIT_MODE, &g_scenario_type, sizeof(g_scenario_type), 1);
		// 	if (ret != 0) 
		// 		ifv_printf(IFV_MSG_ERROR, "Failed to save expo init mode [%d]\n", ret);
		// 	else
		// 		ifv_printf(IFV_MSG_DEBUG, "Successful to save expo init mode [%d]\n", g_scenario_type);
		// }
	}
    g_usbRecogState=1;
    memcpy(userInfo.pose, tp->qa[0].pose, sizeof(userInfo.pose));
	userInfo.tp = pData;
    userCmdArrayCB[2].pfuncmd(&userInfo);
}

void tof_Register_event_callback(int event, void *pData)
{
	int ret = 0;
	int32_t ff_id = 0x7fffffff;
	TsmFaceResult *tp = NULL;
	CmdRegisterCBinfo_S userRegisterInfo;
	// TsmFaceBox *pBox = NULL;

	//LOGD(TAG, "%s \n", __func__);
	tp = (TsmFaceResult *)pData;
	ret = checkFaceResult(tp,1,0);
	if(0 == ret)
	{
		TsmFaceFeatrue *pFeature = &tp->feature;
        TsmFaceFeatrue *pMaskFeature = &tp->mask_feature;
		ff_id = tsm_ff_add(pFeature->vector + pFeature->len * 0, pMaskFeature->vector + pMaskFeature->len * 0);
		if (ff_id >= 0)
		{
			ifv_printf(IFV_MSG_ERROR, "Success to add face feature with id %d\r\n", ff_id);
			userRegisterInfo.result = 0;
			userRegisterInfo.id = ff_id;
			userRegisterInfo.tp = pData;

			//call user register cb function,
			userCmdArrayCB[4].pfuncmd(&userRegisterInfo);
			//registerResultAck(userRegisterInfo.result, userRegisterInfo.id);
		}
	}
	else
	{
		userRegisterInfo.result = ret;
		userRegisterInfo.id = 0xffffffff;
		userRegisterInfo.tp = pData;
		//call user register cb function,
		userCmdArrayCB[4].pfuncmd(&userRegisterInfo);
		//registerResultAck(userRegisterInfo.result, userRegisterInfo.id);
	}
	enroll_or_recognize_busy_flag = 0;
#if 0	//debug
	printAIResult(tp);
#endif

}


void tof_Recognize_event_callback(int event, void *pData)
{
	int ret = 0;
	// TsmFaceBox *pBox = NULL;
	// int max_score_id = 0;
	// float max_score = 0;
	// float matchScore = 0;
	// short *vec = NULL;
	// Match *match = NULL;	
	TsmFaceResult *tp = NULL;
	CmdRecognizeCBinfo_S userInfo;
	// tsmMatchParam g_matchparam_mask;

	if(register_ir_flag)
	{
		tof_Register_event_callback(event, pData);
		register_ir_flag = 0;
		return;
	}
	
	//LOGD(TAG, "%s \n", __func__);
	tp = (TsmFaceResult *)pData;
	ret = checkFaceResult(tp,1,0);
	if(0 == ret)
	{
		userInfo.id = getRecoMaxSimilarityId(tp, faceFeature, 0); //suport only one biger face
		if(userInfo.id == -1)
		{
			userInfo.result = FACE_RESULT_NOT_MATCH;
			userInfo.id = 0x7fffffff;
		}
		else
		{
			userInfo.result = FACE_RESULT_SUCCESS;
			LOGD(TAG, "recognize id: %d \n", userInfo.id);
		}
		userInfo.tp = pData;
		userCmdArrayCB[5].pfuncmd(&userInfo);	
		//recognizeResultAck(userInfo.result, userInfo.id);
	}
	else
	{
		userInfo.result = ret;
		userInfo.id = 0x7fffffff;
		userInfo.tp = pData;
		userCmdArrayCB[5].pfuncmd(&userInfo);
		//recognizeResultAck(userInfo.result, userInfo.id);
	}
	enroll_or_recognize_busy_flag = 0;
#if 0	//debug
	printAIResult(tp);
#endif
}

extern int ff_id2name_get_from_fs(uint32_t id, char *name);
char *ifvGetRegisterNameByID(uint32_t ff_id)
{
    static char buf[128] = {0};
    // char ff_id_name_str[16] = {0};
    // int  len = sizeof(buf);
    int ret;
#ifdef AOS_CONFIG_FF_USE_KV
    memset(buf,0,len);
    sprintf(ff_id_name_str,"name_%d",ff_id);
    ret = aos_kv_get(ff_id_name_str,buf,&len);
    if(ret < 0)
    {
        LOGD(TAG, "Get %d name error\n",ff_id);
        return NULL;
    }
#else
    ret = ff_id2name_get_from_fs(ff_id, buf);
    if (ret < 0) {
        ifv_printf(IFV_MSG_ERROR, "ff get from fs error.\n");
        return NULL;
    }
#endif
    //LOGD(TAG, "%s %s \n",__func__, buf);

    return buf;
}

extern int ff_id2name_add_to_fs(uint32_t id, char *name);
void ifvSetRegisterName(uint32_t ff_id, char *name)
{
    // char ff_id_name_str[16] = {0};
    // int ret;
#ifdef AOS_CONFIG_FF_USE_KV
    sprintf(ff_id_name_str,"name_%d",ff_id);
    ret = aos_kv_set(ff_id_name_str, name, strlen(name), 1);
    if(ret < 0)
        LOGE(TAG, "%s Error.\n",__func__);
#elif defined(AOS_CONFIG_FF_USE_FS)
    ret = ff_id2name_add_to_fs(ff_id, name);
    if (ret < 0) {
        ifv_printf(IFV_MSG_ERROR, "ff add to fs error.\n");
        return -1;
    }
#endif    
}

void if_v_Register_vis_event_callback(int event, void *pData)
{
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_register_cmd;
	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);
	
	cmd2openmax->state = APP2IFV_REGISTER_CMD_STATE_COMPLETE;
	TsmFaceFeatrue *pFeature = NULL;
    TsmFaceFeatrue *pMaskFeature = NULL;
	TsmFaceResult *tp = NULL;
	int ret = 0;	
	// int cmd;
    int32_t ff_id = 0x7fffffff;
	CmdRegisterCBinfo_S userRegisterInfo;

	ifv_printf(IFV_MSG_INFO,"  feature len %d , faceNum %d =\n",  ((TsmFaceResult *)pData)->feature.len, ((TsmFaceResult *)pData)->nFace );
	
	//save feature
	tp = (TsmFaceResult *)pData;

	ifv_printf(IFV_MSG_INFO, "face num : %d \n",tp->nFace);
	ret = checkFaceResult(tp,0,0);
	if(0 == ret)
	{
        pFeature = &((TsmFaceResult *)pData)->feature;
        pMaskFeature = &((TsmFaceResult *)pData)->mask_feature;
        ff_id = tsm_ff_add(pFeature->vector + pFeature->len * 0,pMaskFeature->vector + pMaskFeature->len * 0 );
        ifv_printf(IFV_MSG_INFO, "tsm_ff_add : %lld \n",aos_now_ms() - ifv_stop_time);
		//update feature need before uart ack : by lfcui
		//aie_feature_update(FACE_FEATURE_MAX_NUM,FACE_FEATURE_ADR);
		if (ff_id >= 0)
		{
            ifv_printf(IFV_MSG_ERROR, "Success to add face feature with id %d\r\n", ff_id);
			userRegisterInfo.result = 0;
			userRegisterInfo.id = ff_id;

			if(0 == enroll_from_uart_busy_flag)
			{
				//call user register cb function,
				userCmdArrayCB[0].pfuncmd(&userRegisterInfo);
			}
			else if(1 == enroll_from_uart_busy_flag)
			{
				registerFromUartAck(0,ff_id);
			}
		}
	}
	else
	{
		if(0 == enroll_from_uart_busy_flag)
		{
			userRegisterInfo.result = ret;
			userRegisterInfo.id = 0xffffffff;
			//call user register cb function,
			userCmdArrayCB[0].pfuncmd(&userRegisterInfo);
		}
		else if(1 == enroll_from_uart_busy_flag)	
		{
			registerFromUartAck(1,0xfffffffe);
			//enroll_from_uart_busy_flag = 0;
		}	
	}

    ifv_stop_time = aos_now_ms();
    ifv_printf(IFV_MSG_INFO, "@OUT2 reco=%lld\n", ifv_stop_time);

	enroll_or_recognize_busy_flag = 0;
    startRegisterCmd = 0;
}

void if_v_source_vis_event_callback(int event, void *data)
{
	int cmd;
	int ret=0;
	//ifv_printf(IFV_MSG_INFO," %s event %d \r\n", __func__, event);
	
	switch (event){
		case VIS_STREAM_DECT_EVENT:
			//ifv_printf(IFV_MSG_DEBUG,"IFV Get openmax stream mode\n");
			ret = ifvCmd2OpenmaxLookup(APP2IFV_REGISTER_CMD,&cmd);
			//check is there cmd in queue
			if( ret == APP2IFV_CMD_STATE_NONE ){
				//ifv_printf(IFV_MSG_INFO," no register cmd \r\n" );							
			}else { 				
				ifv_printf(IFV_MSG_INFO," vis switch to CAP mode \r\n" );
				//ifvSetVisMode2Openmax(VIDEO_SRC02_MODE_VIS_CAP);
			}
			break;
		case VIS_CAP_DECT_EVENT:
			ifv_printf(IFV_MSG_DEBUG,"IFV Get openmax cap mode, switch to stream.\n");
			//ifvSetVisMode2Openmax(VIDEO_SRC02_MODE_VIS_STREAM);
			break;
		default:
			break;
	}
}

void if_v_source_spk_event_callback(int event, void *data)
{
	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);
	if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, \
				TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, \
				TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, \
				TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
	//judge spk img mean luma
#if 1
	scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
	ifv_printf(IFV_MSG_INFO,"[LF]===== %s lumacfg scene %d =====\r\n", __func__,lumaCfg.scene);
	if(SENSOR_EXPO_INDOOR == lumaCfg.scene){		
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_INDOOR;
		g_scenario_type = SENSOR_EXPO_INDOOR;
	}
	else if(SENSOR_EXPO_OUTDOOR == lumaCfg.scene){	
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_OUTDOOR;
		g_scenario_type = SENSOR_EXPO_OUTDOOR;
	}

	LOGD(TAG, "[LF]scene type %d, g_scenario_type %d \n",TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type ,g_scenario_type);
#endif 	

	cmd2Openmax_post_sema();
}

void if_v_source_ir_event_callback(int event, void *data)
{
	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);
	switch (event){
		case IR_CAP_IMAGE_SUCCESS_EVENT:
			ifv_printf(IFV_MSG_DEBUG,"IFV Get IR image\n");			
			if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
					TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
					TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
					TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
			//check the exposure_para is ok or not.
#if 0
			scene_judge_meanluma(TX510_IR_defConfig.isp_id, &lumaCfg);
			ifv_printf(IFV_MSG_INFO,"===== %s lumacfg scene %d =====\r\n", __func__,lumaCfg.scene);
			if(SENSOR_EXPO_INDOOR == lumaCfg.scene){
				TX510_IR_defConfig.scenario_type = SENSOR_EXPO_INDOOR;
				g_scenario_type = SENSOR_EXPO_INDOOR;
			}
			else if(SENSOR_EXPO_OUTDOOR == lumaCfg.scene){	
				TX510_IR_defConfig.scenario_type = SENSOR_EXPO_OUTDOOR;
				g_scenario_type = SENSOR_EXPO_OUTDOOR;
			}

			LOGD(TAG, "scene type %d \n",TX510_IR_defConfig.scenario_type);
#endif 			
			//check is there cmd in queue
			cmd2Openmax_post_sema();
//			if(ifvCmd2OpenmaxLookup(APP2IFV_RECOGNIZE_CMD,&cmd) ){	
//				if(VIDEO_SRC02_MODE_SPECKLE == cmd){
//					//ifvSetIRMode2Openmax(cmd);
//					//if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,TX510_IR_defConfig.mipi_id, TX510_IR_defConfig.isp_id, TX510_IR_defConfig.light_type); //new_cap
//					TX510_IR_defConfig.light_type = LED_LIGHT_TYPE_SPK;
//					ifv_printf(IFV_MSG_INFO," %s change mode %s \r\n", __func__,openMaxSrcModeGroup[cmd].name);
//					cmd2Openmax_post_sema();
//				}
//			}else{
//				ifv_printf(IFV_MSG_INFO,"%s cmd not found.\n",__func__);
//				//ifvSetIRMode2Openmax(VIDEO_SRC02_MODE_IR);			
//				//TX510_IR_defConfig.light_type = LED_LIGHT_TYPE_IR;
//			}		
		break;
		case SPK_CAP_IMAGE_SUCCESS_EVENT:			
			ifv_printf(IFV_MSG_DEBUG,"IFV Get SPK image\n");	
			if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
			ifv_printf(IFV_MSG_DEBUG,"IFV set led to default IR.\n");							
			//ifvSetIRMode2Openmax(VIDEO_SRC02_MODE_IR);			
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_IR;
			cmd2Openmax_post_sema();
		break;

		default:
		break;
	}
}

extern int ui_show_register_info(void* info, unsigned char result);
//
void if_v_sink_event_callback(int event, void *data)
{
	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);
	//show text to display
	
}

int if_vEventRegisterCallback (void *pContext, event_handler cb)
{
    ifv_printf(IFV_MSG_INFO,"API not implemented.\n");
	cb(0, NULL);
    return 0;
}

bool if_vConfigLed()
{
    TSM_VI_INFO_S stViInfo = {0};

	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);

//	tsm_vi_pause(&stViInfo);
#if 0
	stViInfo.stSnsInfo.u32MipiId	= MIPI_2; //new_cap
	//stViInfo.stSnsInfo.u32MipiId	= MIPI_1; //binocular
	stViInfo.stPipeInfo.u32PipeId	= ISP_1;
	stViInfo.stLedInfo.enLightType	= LED_LIGHT_TYPE_IR;
	
	aos_msleep(100);
	
	stViInfo.stSnsInfo.u32Expo		= SENSOR_EXPO_INDOOR;
#else
	stViInfo.stSnsInfo.u32MipiId	= TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id;
	stViInfo.stPipeInfo.u32PipeId	= TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id;
	stViInfo.stLedInfo.enLightType	= TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type;
	stViInfo.stSnsInfo.u32Expo		= TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type;

#endif 
	tsm_vi_pause(&stViInfo);
	aos_msleep(100);
	tsm_vi_resume(&stViInfo);
	ifv_printf(IFV_MSG_INFO,"ir led ready\n");
	return true;
}

bool if_vConfigSensorBufIO()
{
	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);

	int ret = 0;
	//remove temp
	//gpio_init();
	//vi_camera_buf_init();
	// set_start_time(30, aos_now_ms());
	// example_pin_camera_iic0_init();
	// example_pin_camera_iic1_init();
	// set_stop_time(30, aos_now_ms());
	
	return ret;
}

// bool if_vConfigSensor(Sensor_e type)
// {
// 	return appConfigSensor(type);
// }

bool if_vDefThresConfigInit(living_detection_config *living_conf, face_detect_config *face_conf)
{
	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);
	return 0;
}

void if_vOpenIsp(int id, int mode) //for rgb/ir
{
	ifv_printf(IFV_MSG_INFO,"===== %s ISP%d %s =====\r\n", __func__,id, mode == 1 ? "STREAM":"STANDBY");
	switch(id){
		case 0:

		break;
		case 1:
		break;
		default:

		break;
	}
}

#define IFV_QUEUE_MAXSLOTS      8
#define IFV_TASK_STACK_SIZE     2*1024
#define IFV_TASK_PRIO           (AOS_DEFAULT_APP_PRI - 4)
#define IFV_QUEUE_MAX_MSG_SIZE  (sizeof(ifv_msg_pkg_t))
#define IFV_QUEUE_MAX_MSG_COUNT (512)
#define IFV_QUEUE_SIZE          (IFV_QUEUE_MAX_MSG_SIZE * IFV_QUEUE_MAX_MSG_COUNT)
#define DEFAULT_TIMER_INTERVAL 1000 /* 1000ms */
aos_queue_t             g_ifv_queue;
char                    g_ifv_msg[IFV_QUEUE_SIZE] = {0};
aos_task_t              g_ifv_task;
aos_task_t 				g_ifv_ISP_task;
aos_task_t 				g_ifv_ISP_cat_eye_task;
aos_task_t 				g_ifv_ISP_RGB_task;
aos_task_t 				g_ifv_ISP_IR_task;
aos_task_t 				g_ifv_JpegRegister_task;
aos_task_t 				g_ifv_Recognize_task;
aos_task_t              g_ifv_usb_task;

int g_test = 0;

void if_vSet_RunningState(uint32_t state)
{
	gIfvRuningState = state;
	
}

uint32_t if_vGet_RunningState()
{
	return gIfvRuningState;
	
}

uint32_t ifvGetFlowState()
{
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	cmd2openmax_list *cmd2openmax_reg = &g_ifv2openmax_register_cmd;	

    ifv_printf(IFV_MSG_INFO,"recog state: %d, reg state %d\n",cmd2openmax->state,cmd2openmax_reg->state);

    switch(cmd2openmax->state){
        case APP2IFV_CMD_STATE_NONE:
        case APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE:
            return MS_STANDBY;
        break;
        case APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY:
        case APP2IFV_RECOGNIZE_CMD_STATE_RIGHT_IR_ENTRY:
        case APP2IFV_RECOGNIZE_CMD_STATE_SPK_ENTRY:
            return MS_BUSY;
        break;

    }

    switch(cmd2openmax_reg->state){
        case APP2IFV_CMD_STATE_NONE:
        case APP2IFV_REGISTER_CMD_STATE_COMPLETE:
             return MS_STANDBY;
        break;

        default:
             return MS_BUSY;
        break;
    }

    return MS_INVALID;
}


extern uint32_t g_snapshot_done ;
#ifndef AOS_BOARD_TX510_PAY
void ifv_ProcessSnap3In1()
{
	unsigned char *pBufferIR = (unsigned char *)MM_USB_BUF_IR;
	unsigned char *pBufferSPK = (unsigned char *)MM_USB_BUF_SPK;
    
	int mipiID=TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id;
	int ispID=TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id;

 	//get rgb
	{
	    TSM_VI_INFO_S stViInfo = {0};
		int led_type = LED_LIGHT_TYPE_RGB;

		stViInfo.stSnsInfo.u32MipiId	= TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].mipi_id;	
		stViInfo.stPipeInfo.u32PipeId	= TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].isp_id; 	
		stViInfo.stLedInfo.enLightType	= led_type;
		stViInfo.stSnsInfo.u32Expo		= TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].scenario_type;
		tsm_vi_pause(&stViInfo);		
	}
	//get ir	
	if_vSet_RunningState(IFV_RUNNING_STATE_SNAP_IR); 
	if_vGetIrSpkSnapShot(mipiID,ispID,1, pBufferIR);	
	//LOGD(TAG, "get snapshot ir pic.\n");

	//get spk
	if_vSet_RunningState(IFV_RUNNING_STATE_SNAP_SPK); 
	if_vGetIrSpkSnapShot(mipiID,ispID,2, pBufferSPK);	
	//LOGD(TAG, "get snapshot spk pic.\n");

	//inform usbdtsm.
	g_snapshot_done =1;
}
#endif

static void ifv_msg_dispatcher(void *arg)
{
    int ret = 0;
    char data[256];
    uint32_t          size = 0;
    ifv_msg_pkg_t *msg  = NULL;

    while (1) {
        size = 0;
#if 1		
        ret = aos_queue_recv(&g_ifv_queue, AOS_WAIT_FOREVER, (void *)data, (unsigned int *)(&size));
        if ((ret != 0) || (size == 0)){			
			ifv_printf(IFV_MSG_DEBUG,"===== recv cmd none =====\n");
            continue;
        }
#else 
		aos_sem_wait((aos_sem_t *)&ifv_cmd_sem_task, AOS_WAIT_FOREVER);


#endif 		
        msg = (ifv_msg_pkg_t *)data;
        
        ifv_printf(IFV_MSG_INFO,"ifv_msg_dispatcher cmd: %d, ifV state %d\n",msg->cmd,if_vGet_RunningState());
        switch(msg->cmd){
        //switch(ifv_cmd_sem_task.type){
            case APP2IFV_CALIBRATION_CMD:
				g_variable_cfg.g_calibration_flag = 1;
				g_variable_cfg.g_sensorCalState = 0;
				printf("calib begin \n");

				CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, SENSOR_CALIB_SETPOINT);
				CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, SENSOR_CALIB_SETPOINT);

				if_vRecognition_process(NULL, NULL, 5);
                break;
			case APP2IFV_CALIB_ESTIMATE_CMD:
				g_variable_cfg.g_calib_estimate_flag = 1;
				g_variable_cfg.g_sensorCalState = 0;

				printf("calib estimate begin \n");

				CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, SENSOR_CALIB_SETPOINT);
				CamEngineAecSetSetpoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, SENSOR_CALIB_SETPOINT);

				if_vRecognition_process(NULL, NULL, 5);
                break;
            case APP2IFV_REGISTER_CMD:
                ifv_printf(IFV_MSG_DEBUG," recv cmd register %d\n",g_test);
		
				if (register_by_ir==0){
					LOGD(TAG, "register by vis!\n");
					if_vRegister(NULL);
				}
				else{
					LOGD(TAG, "register by ir!\n");
					ifv_printf(IFV_MSG_DEBUG,"===== ir register=====\n");
					register_ir_flag = 1;
					if_vRecognition_process(NULL, NULL, 5);
				}
                break;
			case APP2IFV_REGISTER_UART_CMD:
				ifv_printf(IFV_MSG_DEBUG,"===== recv cmd register uart =====\n");

				if (g_ifv_flow_cfg.source_ir_left && g_ifv_flow_cfg.source_ir_right){
					g_ifv_flow_cfg.register_pic = 1;
					iva_2ir_empty_buffer(0, 0);
					iva_2ir_empty_buffer(1, 0);
				}
#if defined(AOS_BOARD_TX510_LOCK_RS)
				else if(1)
				{				
					register_ir_flag = 1;
					iva_facereco_ir_empty_buffer(0,0);					
					iva_facereco_spk_empty_buffer(1,0);
				}
#endif				
				else{
					if_vRegister(NULL);
				}
				break;
			case APP2IFV_REGISTER_EVENT:
                ifv_printf(IFV_MSG_DEBUG,"===== recv event register =====\n");
				break;
			case APP2IFV_RECOGNIZE_CMD:
                ifv_printf(IFV_MSG_DEBUG," recv cmd recognize \n");
                if(APP2IFV_REGISTER_CMD_BATCH_START == if_vGet_RunningState())
                    break;
            
				if(startRegisterCmd == 1) 
               	 ifv_printf(IFV_MSG_WARNING," high priority cmd register \n");
				else{
					//if_vRecognition_process(NULL, NULL, 5);
					if(!aie_vis_reco_enable)
                    	aos_event_set(&recognizeEvents, EVENT_IFV_COGNIZE_PROC, AOS_EVENT_OR);          
				}
				break;
			case APP2IFV_RECOGNIZE_EVENT:
				break;
			case APP2IFV_SNAP_RGB_CMD:

				break;
			case APP2IFV_SNAP_IR_CMD:
                ifv_printf(IFV_MSG_DEBUG,"===== recv Snap IR =====\n");
				if_vSet_RunningState(IFV_RUNNING_STATE_SNAP_IR); 
				userCmdGetIrSpkSnapShot(LED_LIGHT_TYPE_IR);
				break;
			case APP2IFV_SNAP_SPK_CMD:
                ifv_printf(IFV_MSG_DEBUG," recv Snap SPK \n");
				if_vSet_RunningState(IFV_RUNNING_STATE_SNAP_SPK); 
				userCmdGetIrSpkSnapShot(LED_LIGHT_TYPE_SPK);
			case APP2IFV_DEL_USER_CMD:
				ifv_printf(IFV_MSG_DEBUG," recv cmd del user,id %d \n", msg->value);
				ret = if_vDel(msg->value); 
				if (0 > ret)
				{		
					delUserResultAck(0, 1, msg->value);
					ifv_printf(IFV_MSG_ERROR,"Failed to del id\r\n", __func__);
				}
				else
				{		
					delUserResultAck(0, 0, msg->value);
					ifv_printf(IFV_MSG_ERROR,"Success to del id \r\n", __func__);
				}
				break;
			case APP2IFV_DEL_USER_RANGE_CMD:
				ifv_printf(IFV_MSG_ERROR," recv cmd del user range \n");
				{
					uint16_t srcID,dstID;
					dump_le_uint16(&((uint8_t *)(msg->pData))[0], &srcID);
					dump_le_uint16(&((uint8_t *)(msg->pData))[2], &dstID);
					ret = if_vDelRange(srcID, dstID);
					if (0 > ret)
					{		
						delUserResultAck(1, 1, msg->value);
						ifv_printf(IFV_MSG_ERROR,"Failed to del id\r\n", __func__);
					}
					else
					{		
						delUserResultAck(1, 0, msg->value);
						ifv_printf(IFV_MSG_ERROR,"Success to del id \r\n", __func__);
					}
				}
				break;
			case APP2IFV_DEL_ALL_USERS_CMD:
				ifv_printf(IFV_MSG_DEBUG," recv cmd del user \n");
				if_vDelAll();
				break;
			case APP2IFV_GET_USER_INFO_CMD:
				ifv_printf(IFV_MSG_DEBUG," recv cmd get user info \n");
				LOGD(TAG, "get user id %d info \n",msg->value);
				if_vGetUsrInfo(msg->value);
				break;
			case APP2IFV_GET_ALL_USERS_ID_CMD:
				ifv_printf(IFV_MSG_DEBUG," recv cmd get all user id \n");
				LOGD(TAG, "get all user id \n");
				if_vGetAllUsrID();
				break;
			case APP2IFV_SET_THRESH_CMD:
			{
				ifv_printf(IFV_MSG_DEBUG," set thresh \n");
				LOGD(TAG, "set thresh \n");
				if_vSetThreshLevel(((uint8_t *)(msg->pData))[0], ((uint8_t *)(msg->pData))[1]);
				break;
			}	
			case APP2IFV_ISP_START_SET:
				ifv_printf(IFV_MSG_DEBUG," recv cmd isp start \n");
				if_vRgbStreamPauseResume(1);
			break;
			case APP2IFV_ISP_STOP_SET:
				ifv_printf(IFV_MSG_DEBUG," recv cmd isp stop \n");
				if_vRgbStreamPauseResume(0);
			break;
			case APP2IFV_SNAPSHOT_MODE_3IN1:
			ifv_printf(IFV_MSG_DEBUG,"===== snap 3IN1 begin =====\n");
			if (TRAV_PARA_NEED_CHG == trav_cfg)
			{
				aos_sem_signal(&para_traverse_sem);
				aos_sem_wait(&para_traverse_ready_sem, AOS_WAIT_FOREVER);
				if (0 == aos_sem_wait(&para_traverse_complete_sem, AOS_NO_WAIT)) {
					trav_cfg = TRAV_PARA_NO_NEED_CHG;
					set_trav_para_list_invalid();
					para_traverse_task_destroy();
					//LOGD(TAG, "traverse finished!\n");
					//continue;
				}
			}
#ifndef AOS_BOARD_TX510_PAY
			ifv_ProcessSnap3In1();
#endif
			break;
#if defined(SENSOR_PREVIEW_MODE)
			case APP2IFV_STREAM_START:
				LOGD(TAG, "open stream\n");
				sensor_stream(ISP_0);
				sensor_stream(ISP_1);
				isp_start(0); 
				isp_start(1); 
				//#if RGB_IR_SPK_MODE
				//if_vRgbStreamPauseResume(1);
				//#endif
			break;
			case APP2IFV_STREAM_STOP:
				LOGD(TAG, "close stream\n");
				sensor_standby(ISP_0);
				sensor_standby(ISP_1);
				isp_stop(0);
				isp_stop(1);
			break;
#endif
			case APP2IFV_SNAPSHOT_MODE_DONE:
				ifv_printf(IFV_MSG_DEBUG," snap 3IN1 done \n");
				{
						TSM_VI_INFO_S stViInfo = {0};
						int mipi_id = MIPI_1; 
						int isp_id =  ISP_1;
						int led_type = LED_LIGHT_TYPE_RGB;
				
						stViInfo.stSnsInfo.u32MipiId	= mipi_id;	
						stViInfo.stPipeInfo.u32PipeId	= isp_id;	
						stViInfo.stLedInfo.enLightType	= led_type;
						stViInfo.stSnsInfo.u32Expo		= TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].scenario_type;
						tsm_vi_resume(&stViInfo);		
				}

			break;
            default:
                break;
        }
    }
}

int ifv_read_task_creat(void)
{
    int ret;
    ret = aos_queue_new(&g_ifv_queue, (void *)&g_ifv_msg, IFV_QUEUE_SIZE, IFV_QUEUE_MAX_MSG_SIZE);
    if (ret) {
		ifv_printf(IFV_MSG_ERROR,"%s %d \r\n", __func__,__LINE__);		
        return -1;
    }

    ret = aos_task_new_ext(&g_ifv_task, "ifv_msg_dispatch_task", ifv_msg_dispatcher, NULL, 100*IFV_TASK_STACK_SIZE, IFV_TASK_PRIO-10);
    if (ret) {
		ifv_printf(IFV_MSG_ERROR," %s %d \r\n", __func__,__LINE__);		
        return -1;
    }


    aos_sem_new((aos_sem_t *)&ifv_cmd_sem_task, 0);

    return ret;
}

#if 0
void ifv_isp_service()
{
	while(1)
	{
		algo_isp_handle();
		aos_msleep(10);
        
		if (!isp_mi_event[ISP_0] || !isp_mi_event[ISP_1] || !isp_mi_event[ISP_2]) 
		{
			continue;
		}	

		isp_mi_event[ISP_0]  = 0;
		isp_mi_event[ISP_1]  = 0;
		isp_mi_event[ISP_2]  = 0;
		ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);
					
	}
}

int ifv_ISP_task_creat(void)
{
    int ret;
    ret = aos_task_new_ext(&g_ifv_ISP_task, "ifv_isp_task", ifv_isp_service, NULL, IFV_TASK_STACK_SIZE*8, IFV_TASK_PRIO);
    if (ret) {
        return -1;
    }

    return 0;
}
#endif

void ifv_usb_service(void *paras)
{
	while(1)
	{
		ifv_wait_usb_semp();
		if(ifv_usb_semp.type)
		{
			tsm_open_peephole();
		}
		else
		{
			tsm_close_peephole();
		}
	}
}

void ifv_wait_usb_semp(void)
{
	aos_sem_wait((aos_sem_t *)&ifv_usb_semp, AOS_WAIT_FOREVER);
}

void ifv_send_usb_semp(int type)
{
	ifv_usb_semp.type = type;
	aos_sem_signal((aos_sem_t *)&ifv_usb_semp);
}

int ifv_usb_task_creat(void)
{
	int ret = aos_task_new_ext(&g_ifv_usb_task,"ifv_usb_task", ifv_usb_service, NULL,  IFV_TASK_STACK_SIZE*5, IFV_TASK_PRIO);
	if (ret)
	{
		return -1;
	}
	return 0;
}

uint32_t g_ulIfvExpoLoaded = 1;

void ifv_isp_service(void *paras)
{
	int isp_idx = *(int*)paras;
	// uint32_t isp_events = 0;
	uint32_t mis_value = 0;
	uint32_t actflags = 0;
	if(!aos_event_is_valid(&isp_instance[isp_idx].events))
	{
		aos_task_exit(0); 
		return; 
	}
	ifv_printf(IFV_MSG_INFO, "%s=%d\n", __FUNCTION__, isp_idx);
	while(1)
	{
		actflags = 0;
        qw_isp_irq_get(&isp_instance[isp_idx], &actflags, &mis_value);
#if 0
        //LOGD(TAG, "%s %d\r\n", __func__, __LINE__);
        if ((actflags & EVENT_ISP_IR_PROC) && g_face_ae_info.nir_box_ready)
        {
            if (g_ifv_flow_cfg.face_ae_ir)
                face_ae_ir(isp_idx, &g_face_ae_info);
            else
                g_face_ae_info.face_ae_done = true;
        }
#endif        
        if(((actflags & EVENT_ISP_RGB_PROC) && isp_rgb_enable_flag)
            || ((actflags & EVENT_ISP_IR_PROC) && g_ulIfvExpoLoaded))
        {
            aos_mutex_lock(&g_isp_3a_mutex, AOS_WAIT_FOREVER);
            HalIsrHandlerSrc(isp_idx, mis_value);
            aos_mutex_unlock(&g_isp_3a_mutex);
        }
    }
}

int ifv_isp_task_creat(void)
{
	for(uint32_t i=0; i<ISP_NUM; i++)
    {
    	int ret = aos_task_new_ext(&g_ifv_ISP_task, "ifv_isp_task", ifv_isp_service, &g_isp_idx[i], IFV_TASK_STACK_SIZE*4, IFV_TASK_PRIO);
	    if (ret) {
	        return -1;
	    }
	}
    return 0;
}

int ifv_isp_task_delete(void)
{
	for(uint32_t i=0;i<ISP_NUM;i++)
	{
		int ret = aos_task_delete("ifv_isp_task");
		if(ret)
		{
			printf("delete isp %d task failed.\n",i);
			ifv_printf(IFV_MSG_ERROR, "ifv delete isp service delete%d failed!!!\n", i);
		}
	}
	return 0;
}

void ifv_isp_ir_service()
{
#if 0
	uint32_t isp_events = 0;
	uint32_t mis_value = 0;
	uint32_t actflags = 0;
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;

	while(1)
	{
        qw_isp_irq_get(&isp_instance[0], &actflags, &mis_value);
#if  defined(AOS_APP_LOCK_DOUBLE_IR)	
		if(0)	
#else
		if ((g_irSensorConvergent == 1) || !g_ulIfvExpoLoaded)
#endif
		{
			aos_msleep(5);
		}
		else
        {
			if(actflags & EVENT_ISP_IR_PROC)
			{
				//ifv_printf(IFV_MSG_ERROR, ">>>>>>>>>>>>>>>>>>isp-ir proc\n");
				HalIsrHandlerSrc(0, mis_value);
			}
		}
        
        aos_msleep(20);
	}
#endif
}

int ifv_ISP_ir_task_creat(void)
{
    int ret;
    ret = aos_task_new_ext(&g_ifv_ISP_IR_task, "ifv_ir_isp_task", ifv_isp_ir_service, NULL, IFV_TASK_STACK_SIZE*4, IFV_TASK_PRIO);
    if (ret) {
        return -1;
    }

    return 0;
}

#if 1	/* test */
aos_task_t	g_ifv_ISP_IR_CIS_task;
aos_task_t	g_ifv_isp_cis_task[ISP_NUM];
#if 1
inline static void cis_aelock_get(uint32_t *actflags, float *gains, float *integr)
{
	if((aos_event_is_valid(&isp_instance[0].events)) && (ISP_WORKMODE_IR == isp_instance[0].mode))
	{
		qw_isp_ae_lock_get(&isp_instance[0], actflags, gains, integr); return;
	}

	if((aos_event_is_valid(&isp_instance[1].events)) && (ISP_WORKMODE_IR == isp_instance[1].mode))
	{
		qw_isp_ae_lock_get(&isp_instance[1], actflags, gains, integr); return;
	}

	if((aos_event_is_valid(&isp_instance[2].events)) && (ISP_WORKMODE_IR == isp_instance[2].mode))
	{
		qw_isp_ae_lock_get(&isp_instance[2], actflags, gains, integr);
		//LOGD(TAG, "$$$$$$$$$$$$$$$$$$$$$%s$$$$$$$$$$$$$$$$$$$$$ \n", __func__);
		return;
	}
}
#endif

inline static void cis_ae_expo_get(uint32_t isp_idx, float *gains, float *integr)
{
	if(ISP_WORKMODE_IR == isp_instance[isp_idx].mode)
	{
		qw_isp_ae_expo_get(&isp_instance[isp_idx], gains, integr); 
        return;
	}
}

void cis_aelock_save(uint32_t idx)
{
#if 1
	// uint32_t actflags = 0;
	float cis_ae_gains = 0.0f;
	float cis_ae_integr = 0.0f;
	float cis_ae_expo = 0.0f;
    int32_t ret;

    cis_ae_expo_get(idx, &cis_ae_gains, &cis_ae_integr);

    cis_ae_expo = cis_ae_gains * cis_ae_integr;

    ret = aos_kv_set(AEC_KV_EXPO, &cis_ae_expo, sizeof(cis_ae_expo), 1);
    if (ret != 0) 
    {
		ifv_printf(IFV_MSG_ERROR, "Failed to save expo of sensor(isp%d)(%d) \n", idx, ret); // ERROR level for debug
    }
    else
    {
		ifv_printf(IFV_MSG_DEBUG, "Successful to save expo of sensor(isp%d) %f \n", idx, cis_ae_expo);  // ERROR level for debug
    }
#endif 
}
#if 0
void ifv_isp_ir_cis_service()
{
	uint32_t actflags = 0;
	float cis_ae_gains = 0.0f;
	float cis_ae_integr = 0.0f;
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;

	while(1)
	{
        for (uint32_t isp_idx = 0; isp_idx < ISP_NUM; isp_idx++)
        {
            if (g_irSensorConvergent[isp_idx])
            {
                continue;
            }

            if (!g_face_ae_info.nir_box_ready)
            {
                actflags = 0;
                if((isp_instance[isp_idx].ae_lock_judge == true)
                    && aos_event_is_valid(&isp_instance[isp_idx].events) 
                    && (isp_instance[isp_idx].mode == ISP_WORKMODE_IR))
                {
                    qw_isp_ae_lock_get(&isp_instance[isp_idx], &actflags, &cis_ae_gains, &cis_ae_integr);
                    if(actflags & EVENT_ISP_IR_AE_LOCK_PROC) 
                    {
                        ifv_printf(IFV_MSG_DEBUG, 
                                    "CIS_GET_AE_LOCK: isp%d, actflags=0x%08x, ae_gains=%f, ae_integr=%f \n", 
                                    isp_idx, actflags, cis_ae_gains, cis_ae_integr);
                        
                        //LOGD(TAG, "AElock%d\n", isp_idx);
                        g_irSensorConvergent[isp_idx] = 1;
                        isp_instance[isp_idx].ae_lock_judge = false;
                        qw_isp_ae_enable_set(isp_idx, false);
                    }
                }
            }
            else if (g_face_ae_info.face_ae_done)
            {
                //LOGD(TAG, "%s %d, box: %d, ae_done: %d\r\n", 
                //    __func__, __LINE__, g_face_ae_info.nir_box_ready, g_face_ae_info.face_ae_done);
                g_irSensorConvergent[isp_idx] = 1;
                //isp_instance[isp_idx].ae_lock_judge = false;
                qw_isp_ae_enable_set(isp_idx, false);
            }
        }
        
        aos_msleep(10);     
	}
}
#endif

void ifv_isp_cis_service(void *paras)
{
	int isp_idx = *(int*)paras;
	uint32_t actflags = 0;
	float cis_ae_gains = 0.0f;
	float cis_ae_integr = 0.0f;
	// cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
    
	if(!aos_event_is_valid(&isp_instance[isp_idx].ae_events))
	{
		aos_task_exit(0); 
		return;
	}
    
	ifv_printf(IFV_MSG_INFO, "%s=%d\n", __FUNCTION__, isp_idx);
    
	while(1)
	{
        actflags = 0;
        qw_isp_ae_lock_get(&isp_instance[isp_idx], &actflags, &cis_ae_gains, &cis_ae_integr);
        
        if (g_irSensorConvergent[isp_idx])
        {
            continue;
        }
        
        if (actflags & EVENT_ISP_IR_AE_LOCK_PROC)
        {
            //ifv_printf(IFV_MSG_DEBUG, 
            printf("CIS_GET_AE_LOCK: isp%d, actflags=0x%08x, ae_gains=%f, ae_integr=%f \n", 
                        isp_idx, actflags, cis_ae_gains, cis_ae_integr);
            //LOGD(TAG, "AElock%d\n", isp_idx);
            isp_instance[isp_idx].ae_lock_judge = false;
            qw_isp_ae_enable_set(isp_idx, false);
			if ((1 == g_ifv_flow_cfg.source_ir_right) && (ISP_WORKMODE_IR == isp_instance[isp_idx].mode))
			{
				g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 1;
				g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = 1;
			}
			else
			{
				g_irSensorConvergent[isp_idx] = 1;
			}

        }
		else
		{
			 ifv_printf(IFV_MSG_DEBUG, 
                        "%s:%d enter CIS_GET_AE_LOCK is failed: isp=%d, actflags=0x%08x, ae_gains=%f, ae_integr=%f, g_irSensorConvergent=%d\n", 
                        __FUNCTION__,__LINE__,isp_idx, actflags, cis_ae_gains, cis_ae_integr,g_irSensorConvergent[isp_idx]);
		}
	}
}


int ifv_ISP_ir_cis_task_creat(void)
{
	for(int i=0; i<ISP_NUM; i++)
	{
		int ret = aos_task_new_ext(&g_ifv_isp_cis_task[i], "ifv_isp_cis_task", ifv_isp_cis_service, &g_isp_idx[i], IFV_TASK_STACK_SIZE*4, IFV_TASK_PRIO);
	    if (ret) {
			ifv_printf(IFV_MSG_ERROR, "ifv creat cis service task%d failed!!!\n", i);
	        return -1;
	    }
	}
    return 0;
}

int ifv_ISP_ir_cis_task_delete(void)
{
	for(int i=0;i<ISP_NUM;i++)
	{
		int ret = aos_task_delete("ifv_isp_cis_task");
		if(ret)
		{
			ifv_printf(IFV_MSG_ERROR, "ifv delete cis service delete%d failed!!!\n", i);
		}
	}
	return 0;
}
#endif

void spk_scene_judge(void)
{
	scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
	ifv_printf(IFV_MSG_INFO,"[LF]===== %s lumacfg scene %d =====\r\n", __func__,lumaCfg.scene);
	if(SENSOR_EXPO_INDOOR == lumaCfg.scene){
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_INDOOR;
		g_scenario_type = SENSOR_EXPO_INDOOR;
	}
	else if(SENSOR_EXPO_OUTDOOR == lumaCfg.scene){	
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_OUTDOOR;
		g_scenario_type = SENSOR_EXPO_OUTDOOR;
	}
	LOGD(TAG, "[LF]scene type %d, g_scenario_type %d \n",TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type ,g_scenario_type);
}


void ifv_isp_interrupt_service(void *param)
{
	//int i2cNo = 0;
	//int devAddr = 0;
	
	if (g_ifv_flow_cfg.source_ir_left && g_ifv_flow_cfg.source_ir_right)
	{
		while(1){
			//LOGD(TAG, "ifv_isp_interrupt_service \n");
			if_vReadIspMiData(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
		    g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 0;
			//sensor_standby(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
			if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id,
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id,
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type);

			if_vReadIspMiData(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
			g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = 0;
			//sensor_standby(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
			if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].mipi_id,
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id,
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type);

			//ir_led_power_off();

			//CALL omax interface
			//LOGD(TAG, "ai result \n");
			iva_2ir_empty_buffer(/*TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id*/0, 0);
			//LOGD(TAG, "ai result 1 \n");
			iva_2ir_empty_buffer(/*TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id*/1, 0);
			//LOGD(TAG, "ai result 2\n");

            
            aos_timer_stop(&g_double_ir_mi_rx_timer);
			
		}
	}
	else if(g_ifv_flow_cfg.source_ir_left && (!g_ifv_flow_cfg.source_ir_right))
	{
    	while(1){
    		if_vReadIrSpkDataFromISP();
    		cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
            switch(cmd2openmax->state){
                case APP2IFV_CMD_STATE_NONE:
                case APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE:
                {   
                    if( (IFV_RUNNING_STATE_SNAP_IR == if_vGet_RunningState() )
                       || (IFV_RUNNING_STATE_SNAP_SPK == if_vGet_RunningState())    ){
                            if_vNotifyIspSnapData(1);
                      }else{
                            if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
                            ifv_printf(IFV_MSG_INFO,"\n %s usless INT\r\n", __func__);
                      }
                }
                break;
                case APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY:
                    if(g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] == 1 ){
						g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 0;
						if (!g_ifv_flow_cfg.source_ir_right)
                        {
                            iva_facereco_ir_empty_buffer(0,0);
                        }
                        else
                        {
                            iva_2ir_empty_buffer(0, 0);
                        }
    					if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
    						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
    						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
    						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type);
    					cmd2Openmax_post_sema();
                    }

                break;
                case APP2IFV_RECOGNIZE_CMD_STATE_RIGHT_IR_ENTRY:
                    if(g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] == 1 ){
						g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = 0;
						iva_2ir_empty_buffer(1, 0);
	                    if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
	                    	TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].mipi_id, 
	                    	TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, 
	                    	TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type);
	                    	cmd2Openmax_post_sema();
                    }

                break;
                case APP2IFV_RECOGNIZE_CMD_STATE_SPK_ENTRY:
					iva_facereco_spk_empty_buffer(1,0);
					//get_sensor_info_by_isp_idx(0, &i2cNo, &devAddr);
					sensor_standby(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
					if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type);
					spk_scene_judge();
					cmd2Openmax_post_sema();
                break;

                default:
                    ifv_printf(IFV_MSG_ERROR,"%s wrong state.\n", __func__);
                break;

            }
    	}
    }
	else if(g_ifv_flow_cfg.source_ir_tof)
	{
    	while(1){
    		if_vReadIrSpkDataFromISP();
    		cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
            switch(cmd2openmax->state){
                case APP2IFV_CMD_STATE_NONE:
                case APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE:
                {   
                    if( (IFV_RUNNING_STATE_SNAP_IR == if_vGet_RunningState() )
                       || (IFV_RUNNING_STATE_SNAP_SPK == if_vGet_RunningState())    ){
                            if_vNotifyIspSnapData(1);
                      }else{
                            if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
								TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
							LOGD(TAG, "sensor standby!\n");
                            ifv_printf(IFV_MSG_INFO,"\n %s usless INT\r\n", __func__);
                      }
                }
                break;
                case APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY:
                    //if(g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] == 1 ){
						//g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 0;
                    {
						iva_tof_reco_ir_empty_buffer(0,0);
    					if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
    						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
    						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
    						TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type);
    					cmd2Openmax_post_sema();
                    }

                break;
                default:
                    ifv_printf(IFV_MSG_ERROR,"%s wrong state.\n", __func__);
                break;

            }
    	}
    }
}

int ifv_isp_interrupt_task_creat(void)
{
    int ret;
    ret = aos_task_new_ext(&g_ifv_ISP_task, "ifv_isp_int_task", ifv_isp_interrupt_service, NULL, 10*IFV_TASK_STACK_SIZE, AOS_DEFAULT_APP_PRI);
    if (ret) {
        return -1;
    }

    return 0;
}


void ifv_test_timer_process()
{
	ifv_msg_pkg_t msg;

	ifv_printf(IFV_MSG_INFO,"\n >>>>>>>>>>1 %s <<<<<<<<<<<<\r\n", __func__);
	ifv_start_time = aos_now_ms();
	//LOGD(TAG, "@IN=%d\n", ifv_start_time);
	//only for test 	
	msg.cmd = APP2IFV_RECOGNIZE_CMD;
	ifv_post_msg(msg);
//	msg.cmd = APP2IFV_REGISTER_CMD;
//	ifv_post_msg(msg);

}

void ifvLoadFaceFeatureInfo()
{
	int ret = 0;
    int fd = -1;
    struct aos_stat file_st;
    uint32_t file_len=0;

    fd = aos_open((const char*)"/mmc/face_feature.bin", O_RDONLY);
    if (fd < 0) 
    {
        LOGD(TAG, "aos_open err.\n");
        goto exit;
    }
    ret = aos_stat("/mmc/face_feature.bin", &file_st);
    if (!ret) {
        file_len = file_st.st_size;
    }
    
    LOGD(TAG, "file len %d\n",file_len);
    ret = aos_read(fd, (uint8_t *)faceFeature, file_len);
    LOGD(TAG, "ret %d\n",ret);

	ifv_printf(IFV_MSG_INFO,"load face feature done \r\n", __func__);
exit:
    if(fd >= 0){
        aos_close(fd);
    }

}


void ifv_register_aie_info()
{
    int32_t retval;
#if defined(FACE_FEATURE_BIN_FILE)
    ifvLoadFaceFeatureInfo();
#else
    retval = tsm_ff_load();
//	if(retval != 0)	
//	{
//		LOGD(TAG, "tsm ff load failed\n");
//		//return -1;
//	}
//	else
	LOGD(TAG, "load ff\n");
	ifv_printf(IFV_MSG_INFO,"load face feature done \r\n", __func__);
#endif
	//tsm_ff_clear();
	//tsm_ff_dump_id();
	g_aie_init_ff = 1;
}


void ifv_jpeg_register_service()
{	
	cmd2openmaxJpeg_list *cmd_node = NULL;
	while(1){
		aos_sem_wait((aos_sem_t *)&ifvJpegRegisterSem, AOS_WAIT_FOREVER);	
		// cmd2openmaxJpeg_list *cmd2openmax = &g_ifv2openmax_jpeg_register_cmd;
		dlist_for_each_entry(&g_ifv2openmax_jpeg_register_cmd_list, cmd_node, cmd2openmaxJpeg_list , linked_list) {
			if(cmd_node->flag){				
				ifv_printf(IFV_MSG_INFO," %s Jpeg register request \r\n", __func__ );	
				
				omx_register_from_IFV(cmd_node->jpeg_reg_info.buff, cmd_node->jpeg_reg_info.pic_size);
				memset(cmd_node,0,sizeof(cmd2openmaxJpeg_list));
				list_del((list_t *)&cmd_node->linked_list);
				break;
			}
		}
	};
}

// void vis_rtalgo_task(void *paras)
// { 	
// 	while(aie_vis_detect_enable)
// 	{	
// 		aos_msleep(120);
// 		omx_visdetect_empty_outbuffer(0,0, MM_IMG_RGB_BUF1);
// 	}
// }

void if_vSetVisDetect(bool flag)
{
	aie_vis_detect_enable = flag;
	//if(aie_vis_detect_enable)
		//aos_task_new("vis_rtalgo_task", vis_rtalgo_task, NULL, 10240);
}

void if_vSetVisReco(bool flag)
{
	aie_vis_reco_enable = flag; 
    //aie_vis_detect_enable = flag;
    if_vSetVisDetect(flag);
}

int ifv_getIspExpValueKv(float *ir_exp)
{
	if(ir_exp == NULL)
	{
		return -1; 
	}
// #if 0
// 	int len = sizeof(irreco_exp);
// 	int ret = aos_kv_get(AEC_KV_EXPO, &irreco_exp, &len);
// 	if (ret)
// 	{
// 		LOGD(TAG, "Failed to load expo of sensor %d \n", ret);
//         irreco_exp = 0;
// 		return -1;
// 	}
// #else
// #if defined(FACE_AE_INIT_GAIN) && defined(FACE_AE_INIT_INTI)
//     irreco_exp = FACE_AE_INIT_GAIN * FACE_AE_INIT_INTI;
// #else
//     irreco_exp = 0;
// #endif
// #endif

	int expoInitMode = 0;
	int len = sizeof(expoInitMode);
	int ret = aos_kv_get(AEC_KV_EXPO_INIT_MODE, &expoInitMode, &len);
	if (ret)
	{
		LOGD(TAG, "Failed to load expo init mode of sensor %d \n", ret);
	}

	g_scenario_type = expoInitMode;

#if defined(INDOOR_INIT_GAIN) && defined(INDOOR_INIT_INTI)  && defined(OUTDOOR_INIT_GAIN)  && defined(OUTDOOR_INIT_INTI)
	if (SENSOR_EXPO_INDOOR == expoInitMode)
    	irreco_exp = INDOOR_INIT_GAIN * INDOOR_INIT_INTI;
	else if (SENSOR_EXPO_OUTDOOR == expoInitMode)
		irreco_exp = OUTDOOR_INIT_GAIN * OUTDOOR_INIT_INTI;
	else
		irreco_exp = 0;
#else
    irreco_exp = 0;
#endif

	*ir_exp  = irreco_exp;
	LOGD(TAG, "get exp value=%f\n", irreco_exp);
	return 0;
}
#if 0
int ifv_getIspSetPointValueKv()
{
	int len = sizeof(irreco_set_point);
	int ret = aos_kv_get(AEC_KV_SETPOINT, &irreco_set_point, &len);
	if (ret)
	{
		LOGD(TAG, "Failed to load set point %d \n", ret);
        irreco_set_point = 0;
		return -1;
	}
	LOGD(TAG, "get set point value=%f\n", irreco_set_point);
	return 0;
}
#endif
int ifv_getFaceXYValueKv()
{
    int len = sizeof(TsmFaceBox);
	int ret = aos_kv_get(AEC_KV_FACE_XY, &g_face_ae_info.nirBox, &len);
	if (ret)
	{
		LOGD(TAG, "Failed to load face coordinate %d \n", ret);
        memset(&g_face_ae_info.nirBox[0], 0x00, sizeof(TsmFaceBox));
		return -1;
	}
	ifv_printf(IFV_MSG_DEBUG, "get face coordinate [%f, %f], [%f, %f]\n", 
	    g_face_ae_info.nirBox[0].xmin,
	    g_face_ae_info.nirBox[0].ymin,
	    g_face_ae_info.nirBox[0].xmax,
	    g_face_ae_info.nirBox[0].ymax);
	return 0;
}

int ifv_setIspexp(uint32_t isp_idx)
{
	IspEngineConfigStartEXP(isp_idx, irreco_exp);
	return 0;
}	

int ifv_setIspSetPoint(uint32_t isp_idx)
{
	IspEngineConfigStartSetPoint(isp_idx, irreco_set_point);
	return 0;
}	

int ifv_GetAieRunModeParamKV()
{
    int len = sizeof(uint8_t);
	int ret = aos_kv_get(IFV_RUNMODE_COVER,&g_runmode_cover, &len);
    if (ret != 0) 
    {
		g_runmode_cover = false;
        LOGD(TAG, "get run mode cover failed\r\n");
		return -1;
    }
	LOGD(TAG, "AIE:Cover:%d\r\n",g_runmode_cover);	
	return 0;
}

int ifv_GetAieReasultPrintParamKV()
{
	int len = sizeof(uint8_t);
	int ret = aos_kv_get(IFV_AIERESULT_PRINT_TIMES,&g_aieresult_print, &len);
    if (ret != 0) 
    {
		g_aieresult_print = false;
        LOGD(TAG, "get aieresult_print failed\r\n");
		return -1;
    }
	LOGD(TAG, "Get aieresult_print is %d\r\n",g_aieresult_print);
	return 0;
}

bool if_vInitial_vis()
{
	ifv_Initial_visbuffer();

	set_start_time(10, aos_now_ms());
	omx_init(ifv_cb);
	set_stop_time(10, aos_now_ms());
	
	set_start_time(101, aos_now_ms());
	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp0, 0);
  	omx_facereco_visstream();
	set_stop_time(101, aos_now_ms());

	//aos_msleep(5);
#if JPEG_CROP_MALLOC_ALL_TIME
    jpg_pic_crop_AI_init();
#endif
	return true;
}

bool if_vInitial_iva_aie()
{
	//ifv_GetAieReasultPrintParamKV();
	
	if ((g_ifv_flow_cfg.preview_mode==UVC_NONE_MODE)
        && g_ifv_flow_cfg.ck805_enable)
	{ 
		//ifv_GetAieRunModeParamKV();
		set_start_time(16, aos_now_ms());
		omx_facereco_aieinit();
		set_stop_time(16, aos_now_ms());
	}  
	return 0;
}

bool if_vInitial_iva_sl3d()
{
	//ifv_GetAieReasultPrintParamKV();
	
	if (g_ifv_flow_cfg.source_spk || g_ifv_flow_cfg.depth_doubleIr_enable)
    {
        set_start_time(15, aos_now_ms());
        omx_facereco_sl3dinit();
        set_stop_time(15, aos_now_ms());
    }
	return 0;
}

	
bool if_vInitial_ff()
{
#if defined(AOS_COMP_FATFS) || defined(AOS_COMP_LITTLEFS)
	if (create_ff_dir_and_files() < 0) {
		LOGD(TAG, "init ff error.\n");
		return -1;
	}
	//load feature
#endif
	set_start_time(12, aos_now_ms());
	ifv_register_aie_info();
	set_stop_time(12, aos_now_ms());
	return 0;
}

bool if_vInitIal_IR_AE()
{
    //CamEngineAecRestart(ISP_ENGINE_IR);
	//ifv_ISP_ir_cis_task_creat();
	return 0;
}

void ifv_recognize_service()
{
    unsigned int flag;
	aos_event_new(&recognizeEvents, 0);
    while(1){
		aos_event_get(&recognizeEvents, EVENT_IFV_COGNIZE_PROC, AOS_EVENT_OR_CLEAR, &flag, AOS_WAIT_FOREVER);
        
        ifv_printf(IFV_MSG_INFO, "%s[0x%x] recv recognize from msg queue\r\n", __func__,flag);
        if(flag & EVENT_IFV_COGNIZE_PROC){
            if_vRecognition_process(NULL, NULL, 5);
        }
        //aos_msleep(10);
    }
}

int ifv_Initial_visbuffer()
{
	uint32_t temp;
	//g_vis_buffer[0] = MM_IMG_ISP1_BUF0;
	//g_vis_buffer[1] = MM_IMG_ISP1_BUF0;

    if (g_vis_buffer[0]) {
        return 0;
	}
    
	g_vis_buffer[0] = aos_malloc(MM_IMG_SIZE_RGB + 256);
	if(g_vis_buffer[0] == NULL)
	{
		ifv_printf(IFV_MSG_ERROR,"%s:malloc mem failed \r\n", __func__);
		return -1;
	}
	temp = (uint32_t)g_vis_buffer[0];
	temp  = temp + 256;
	g_vis_buffer[0] = (uint8_t *)(temp & 0xffffff00);


	g_vis_buffer[1] = aos_malloc(MM_IMG_SIZE_RGB + 256);
	if(g_vis_buffer[1] == NULL)
	{
		ifv_printf(IFV_MSG_ERROR,"%s:malloc mem failed \r\n", __func__);
		return -1;
	}
	temp = (uint32_t)g_vis_buffer[1];
	temp  = temp + 256;
	g_vis_buffer[1] = (uint8_t *)(temp & 0xffffff00);

	//g_vis_buffer[2] = MM_IMG_ISP1_BUF0;
	g_vis_buffer[2] = aos_malloc(MM_IMG_SIZE_RGB + 256);
	if(g_vis_buffer[2] == NULL)
	{
		ifv_printf(IFV_MSG_ERROR,"%s:malloc mem failed \r\n", __func__);
		return -1;
	}
	temp = (uint32_t)g_vis_buffer[2];
	temp  = temp + 256;

	g_vis_buffer[2] = (uint8_t *)(temp & 0xffffff00);
//	g_vis_buffer[6] = MM_IMG_ISP1_BUF0;
//	g_vis_buffer[7] = g_vis_buffer[2];



	g_vis_buffer_num = 3;
	return 0;
}

void double_ir_mi_timer_process()
{
    //
    LOGD(TAG, "%s \n",__func__);

//    hal_reboot();
//
//    while(1);
    int ret = 0;
    cmd2openmax_list *cmd2openmax_recog = &g_ifv2openmax_recognize_cmd;
    cmd2openmax_list *cmd2openmax_register = &g_ifv2openmax_register_cmd;

	if( cmd2openmax_recog->state == APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY ) 
    {   
        mipi_restart(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
        mipi_restart(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
        isp_reset(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
        isp_reset(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);

        ir_led_power_off();

        //aos_event_free(&isp_instance[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id].events);
        //aos_event_free(&isp_instance[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id].events);
        //aos_event_free(&isp_instance[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id].ae_events);
        //aos_event_free(&isp_instance[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id].ae_events);
        
        ret = sensor_reinit();
		isp_cfg_trangle_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
		isp_cfg_trangle_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);

        
        g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 0;
        sensor_standby(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
        g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id] = 0;
        sensor_standby(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
        
        cmd2openmax_recog->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
        cmd2openmax_register->state = APP2IFV_REGISTER_CMD_STATE_COMPLETE;
        
        enroll_or_recognize_busy_flag=0;
        enroll_from_uart_busy_flag=0;


        if(g_irSensorLeftCapMode == 0){
            if_vNotifyIspMiData(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
            //iva_2ir_empty_buffer(/*TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id*/1, 0);
            g_irSensorRightCapMode =0;
        }
        
        if(g_irSensorRightCapMode == 0){
            if_vNotifyIspMiData(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            //iva_2ir_empty_buffer(/*TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id*/0, 0);
            g_irSensorLeftCapMode = 0;
        }

        if(g_irSensorLeftCapMode && g_irSensorRightCapMode){
            if_vNotifyIspMiData(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            if_vNotifyIspMiData(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
            g_irSensorLeftCapMode = 0;
            g_irSensorRightCapMode =0;
            }

        }
}

bool if_vInitial(UserCmdCB *cb, data_flow_func_control_t flow_cfg)
{
    int i = 0;
    int len = sizeof(ifvRandomKey);
	userCmdArrayCB = cb;
    uint32_t res_width;
    uint32_t res_height;

    memcpy(&g_ifv_flow_cfg, &flow_cfg, sizeof(data_flow_func_control_t));
    
	ifv_printf(IFV_MSG_INFO,"Enter" " %s \r\n", __func__);

    srand((int)time(NULL));
    memset(ifvRandomKey,0,len);
    for (i = 0; i < len; i++) {
        ifvRandomKey[i] = (unsigned char)(rand() % 255 + 1);
    }

    if(g_ifv_flow_cfg.jpeg_proc_enable){
        g_ifv_pic_register = (char*)aos_malloc(CROP_PIC_WIDTH * CROP_PIC_HIGHT * 4);
        if (NULL == g_ifv_pic_register)
        {
            LOGD(TAG, "[%s %d] Failed to allocate memory\r\n", __func__, __LINE__);
        }
    }
    
	if(g_ifv_flow_cfg.mask_enable)
	{
		faceFeature = (uint8_t *)aos_malloc(g_ifv_flow_cfg.max_face_num * FACE_FEATURE_SIZE * 2);
		if (NULL == faceFeature)
		{
			LOGD(TAG, "Failed to allocate memory. %s %d\r\n", __func__, __LINE__);
		}
		faceMaskFeature = faceFeature + g_ifv_flow_cfg.max_face_num * FACE_FEATURE_SIZE;
	}
	else
	{
		faceFeature = (uint8_t *)aos_malloc(g_ifv_flow_cfg.max_face_num * FACE_FEATURE_SIZE);
		if (NULL == faceFeature)
		{
			LOGD(TAG, "Failed to allocate memory. %s %d\r\n", __func__, __LINE__);
		}
	}

#ifdef BCTC_TEST
	g_bctc.faceImage = (unsigned char *)aos_malloc(640*360);
	if (NULL == g_bctc.faceImage)
    {
        LOGD(TAG, "[%s %d] Failed to allocate memory\r\n", __func__, __LINE__);
    }
#endif

	memset(g_face_ae_info.nirBox, 0x00, sizeof(TsmFaceBox) * ISP_NUM);
    memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
    memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);
	memset(g_face_ae_info.nirFace, 0x00, sizeof(int32_t) * ISP_NUM);
    g_face_ae_info.loop_counter = 1;
	g_face_ae_info.face_ae_ir = g_ifv_flow_cfg.face_ae_ir;

    omx_init(ifv_cb);
    
	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp_ir, 0);
	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp_spk, 0);
	aos_sem_new((aos_sem_t *)&ifvRecongIrSemp, 0);
	aos_sem_new((aos_sem_t *)&ifvCmd2OpenmaxSemp,0);
	aos_sem_new((aos_sem_t *)&ifvDataIrSpkSemp_isp,0);
	aos_sem_new((aos_sem_t *)&ifvSnapDataSemp_isp,0);
	aos_sem_new((aos_sem_t *)&ifvJpegRegisterSem,0);
	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp0, 0);
	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp_rgb, 0);

	aos_sem_new((aos_sem_t *)&ifv_mi_ir_rgb_semp,0);

	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp0_mi0, 0);
	aos_sem_new((aos_sem_t *)&ifvDataSemp_isp1_mi0, 0);
    aos_sem_new((aos_sem_t *)&ifvDataSemp_isp2_mi0, 0);
    aos_mutex_new(&g_isp_3a_mutex);

	if (g_ifv_flow_cfg.preview_mode==UVC_NONE_MODE)
    {   
        if(g_ifv_flow_cfg.jpeg_proc_enable){
//            JpegCacheRAM = (char *)aos_malloc(512 * 1024 * 4);
            JpegCacheRAM = (char *)aos_malloc(1024 * 1024 * 1);
			
            if (NULL == JpegCacheRAM)
            {
                LOGD(TAG, "[%s %d] Failed to allocate memory\r\n", __func__, __LINE__);
        		//return 1;
            }
        }
        //memset(JpegCacheRAM, 0, 512 * 1024 * 4);
        
		if(g_ifv_flow_cfg.recog_vis_enable || g_ifv_flow_cfg.register_vis)
		{
			set_start_time(16, aos_now_ms());
			omx_facereco_vis();
			set_stop_time(16, aos_now_ms());
		}

		if(g_ifv_flow_cfg.cat_eye_enable)
		{
			omx_cat_eye();
			cfg_cat_eye_mi_buffer();
			ifv_usb_task_creat();
		}

		set_start_time(17, aos_now_ms());

        if ((!g_ifv_flow_cfg.source_ir_right)&&(g_ifv_flow_cfg.source_ir_left))
        {
            isp_res_map(g_ifv_flow_cfg.enResIR, &res_width, &res_height);
            omx_facereco_ir(res_height, res_width);
            set_stop_time(17, aos_now_ms());
			isp_cfg_single_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
//            isp_stop(0);
//            cfg_sensor_mi_buffer(0); 
//            isp_start(0);
#if defined (MINI_STRUCTURE_LIGHT_MODULE)
			lcd_init_config();
#endif
        }
		else if(g_ifv_flow_cfg.source_ir_tof)
		{
			omx_facereco_tof();
		}
        else if(g_ifv_flow_cfg.source_ir_left && g_ifv_flow_cfg.source_ir_right)
        {
            aos_timer_new_ext(&g_double_ir_mi_rx_timer, double_ir_mi_timer_process, NULL,1000*2, 0, 0);                   
            isp_res_map(g_ifv_flow_cfg.enResIR, &res_width, &res_height);
            omx_facereco_2ir(res_height, res_width);

            isp_cfg_trangle_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
			isp_cfg_trangle_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
        }

		// if(g_ifv_flow_cfg.cat_eye_enable)
		// {
		// 	omx_cat_eye();
		// 	cfg_cat_eye_mi_buffer();
		// }

//		if( g_ifv_flow_cfg.register_vis)
//		{
//			set_start_time(18, aos_now_ms());
//			omx_facereco_pic();
//			set_stop_time(18, aos_now_ms());
//		}
	}

	if (g_ifv_flow_cfg.preview_mode == UVC_NONE_MODE)
	{	
		if(g_ifv_flow_cfg.cat_eye_enable)
			ifv_ISP_cat_eye_interrupt_task_creat();
		ifv_isp_interrupt_task_creat();
    	ifv_isp_task_creat();
		ifv_read_task_creat();
   	 	aos_task_new_ext(&g_ifv_Recognize_task, "ifv_recognize_service_task", ifv_recognize_service, NULL, IFV_TASK_STACK_SIZE*10, IFV_TASK_PRIO);
		ifv_ISP_ir_cis_task_creat();
	}
	else if (g_ifv_flow_cfg.preview_mode != UVC_NONE_MODE)
	{
		ifv_ISP_MI_interrupt_task_creat();
	}
	else 
	{
		;
	}
	g_sys_init_done = 1;
//	if( g_ifv_flow_cfg.register_vis){
//		aos_task_new_ext(&g_ifv_JpegRegister_task, "ifv_Jpeg_task", ifv_jpeg_register_service, NULL, IFV_TASK_STACK_SIZE, IFV_TASK_PRIO);
//	}

//    if (g_ifv_flow_cfg.source_ir_left)
//    	if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,
//    	                        TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
//    	                        TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
//    	                        TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
//
//    if (g_ifv_flow_cfg.source_ir_right)
//    	if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,
//    	                        TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].mipi_id, 
//    	                        TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, 
//    	                        TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type); //new_cap
//  aos_timer_new_ext(&g_ifv_test_timer, ifv_test_timer_process, NULL,20000, 1, 1);                   
//  if_v_cli_register();
	ifv_printf(IFV_MSG_INFO,"Leave" "===== %s =====\r\n", __func__);
	return 0;
}

bool if_vInitial_preview(data_flow_func_control_t flow_cfg)
{
	uint32_t res_width;
    uint32_t res_height;

	aos_sem_new((aos_sem_t *)&ifv_mi_ir_rgb_semp,0);

	memcpy(&g_ifv_flow_cfg, &flow_cfg, sizeof(data_flow_func_control_t));

	isp_res_map(g_ifv_flow_cfg.enResIR, &res_width, &res_height);
	if(g_ifv_flow_cfg.preview_mode == UVC_DUAL_IR_MODE)
	{
		omx_dual_ir_preview(res_width,res_height);
	}
	else
	{
		omx_preview_cap(res_width,res_height);
	}
	
	if(g_ifv_flow_cfg.source_ir_right)
	{		
        isp_cfg_preview_trangle_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id,res_width,res_height);
		isp_cfg_preview_trangle_buffer(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id,res_width,res_height);
	}
	
	ifv_ISP_task_creat();
	ifv_read_task_creat();
	ifv_ISP_MI_interrupt_task_creat();
	g_sys_init_done = 1;
	return true;
}

bool if_vInitial_lamp(UserCmdCB *cb)
{
	userCmdArrayCB = cb;
	
	set_start_time(10, aos_now_ms());
	omx_init(ifv_cb);
	set_stop_time(10, aos_now_ms());

#if 1
	set_start_time(101, aos_now_ms());
	//aos_sem_new((aos_sem_t *)&ifvDataSemp_isp0, 0);
  	omx_facereco_visstream();
	set_stop_time(101, aos_now_ms());

	set_start_time(16, aos_now_ms());
	omx_facereco_aieinit();
	set_stop_time(16, aos_now_ms());
	
#else
	omx_preview_gc1054();
#endif
	
	g_aie_init_flag = 1;

	return 0;
}

int32_t ifv_sensor_mode_switch(uint32_t mode, uint32_t buf_idx)
{
#if 1
    scene_judge_meanluma(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, &lumaCfg);
	if(SENSOR_EXPO_INDOOR == lumaCfg.scene){
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_INDOOR;
		g_scenario_type = SENSOR_EXPO_INDOOR;
	}
	else if(SENSOR_EXPO_OUTDOOR == lumaCfg.scene){	
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].scenario_type = SENSOR_EXPO_OUTDOOR;
		g_scenario_type = SENSOR_EXPO_OUTDOOR;
	}
	//LOGD(TAG, "scene type %d, g_scenario_type %d \n",TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR1].scenario_type ,g_scenario_type);
#endif

    if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY, 
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
            mode); //new_cap
    switch (mode)
    {
        case LED_LIGHT_TYPE_IR:
            iva_ir_empty_buffer(OMX_IR_PORT_IDX,buf_idx);
			iva_spk_empty_buffer(OMX_SPK_PORT_IDX,buf_idx);
            break;
        case LED_LIGHT_TYPE_SPK:
			#if defined(SENSOR_PREVIEW_MODE)
			//ov9282_config_spk_strobe_time();
			#endif
            break;
        default:
            break;
    }
    if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME, 
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, 
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, 
            mode); //new_cap
	return 0;
}


int ispReadIntFromIspRgb(int *outType)
{
	aos_sem_wait((aos_sem_t *)&ifv_mi_ir_rgb_semp, AOS_WAIT_FOREVER);
	*outType = ifv_mi_ir_rgb_semp.type;
	return 0;
}

void ifv_isp_mi_interrupt_service()
{
	int mi_channel;
	while(1){
		ispReadIntFromIspRgb(&mi_channel);
		LOGD(TAG, "ifv_mi_ir_rgb_semp.type : %d\n",ifv_mi_ir_rgb_semp.type);
		if(g_ifv_flow_cfg.preview_mode == UVC_RGB_IR_SPK_MODE){      
			switch(mi_channel){
				case 0x2:
					iva_uvc_empty_buffer(OMX_RGB_PORT_IDX,ISP_RGB_BUF_IDX_0);
				break;
				case 0x4:
					iva_uvc_empty_buffer(OMX_RGB_PORT_IDX,ISP_RGB_BUF_IDX_1);
				break;
				case 0x8:
					iva_uvc_empty_buffer(OMX_RGB_PORT_IDX,ISP_RGB_BUF_IDX_2);
				break;
				case 0x10:
					iva_uvc_empty_buffer(OMX_RGB_PORT_IDX,ISP_RGB_BUF_IDX_3);
				break;
				case 0x20:
					iva_uvc_empty_buffer(OMX_RGB_PORT_IDX,ISP_RGB_BUF_IDX_4);
				break;
				case 0x40:
					iva_uvc_empty_buffer(OMX_RGB_PORT_IDX,ISP_RGB_BUF_IDX_5);
				break;
				case 0x03:
				//ir
                	ifv_sensor_mode_switch(LED_LIGHT_TYPE_SPK, ISP_IR_BUF_IDX_0);
				break;
				case 0x05:
				//spk
                	ifv_sensor_mode_switch(LED_LIGHT_TYPE_IR, ISP_IR_BUF_IDX_0);
				//iva_uvc_empty_buffer(OMX_IR_PORT_IDX, ISP_IR_BUF_IDX_0);
				break;
				case 0x09:
				//ir 
                	ifv_sensor_mode_switch(LED_LIGHT_TYPE_SPK, ISP_IR_BUF_IDX_1);
				break;
				case 0x11:
				//spk
                	ifv_sensor_mode_switch(LED_LIGHT_TYPE_IR, ISP_IR_BUF_IDX_1);
				//iva_uvc_empty_buffer(OMX_IR_PORT_IDX, ISP_IR_BUF_IDX_1);
				break;
				case 0x21:
				//ir 
                	ifv_sensor_mode_switch(LED_LIGHT_TYPE_SPK, ISP_IR_BUF_IDX_2);
				break;
				case 0x41:
				//spk
                	ifv_sensor_mode_switch(LED_LIGHT_TYPE_IR, ISP_IR_BUF_IDX_2);
				//iva_uvc_empty_buffer(OMX_IR_PORT_IDX, ISP_IR_BUF_IDX_2);
				break;				
				default:
				break;
			}
		} 
		else if(g_ifv_flow_cfg.preview_mode == UVC_SPK_IR_DEPTH_MODE){
			switch(mi_channel){
				case 0x3:
					ifv_sensor_mode_switch(LED_LIGHT_TYPE_SPK,ISP_IR_BUF_IDX_0);
				break;
				case 0x5:
					ifv_sensor_mode_switch(LED_LIGHT_TYPE_IR,ISP_IR_BUF_IDX_0);
				break;
				case 0x9:
					ifv_sensor_mode_switch(LED_LIGHT_TYPE_SPK,ISP_IR_BUF_IDX_1);
				break;
				case 0x11:
					ifv_sensor_mode_switch(LED_LIGHT_TYPE_IR,ISP_IR_BUF_IDX_1);
				break;
				case 0x21:
					ifv_sensor_mode_switch(LED_LIGHT_TYPE_SPK,ISP_IR_BUF_IDX_2);
				break;
				case 0x41:
					ifv_sensor_mode_switch(LED_LIGHT_TYPE_IR,ISP_IR_BUF_IDX_2);
				break;
				default:
				break;	
			}
		} else if(g_ifv_flow_cfg.preview_mode == UVC_DUAL_IR_MODE)
		{
			switch(mi_channel){
				case 0x2:
					iva_dual_ir_empty_buffer(OMX_LEFT_IR_PORT_IDX,ISP_IR_LEFT_BUF_IDX_0);
				break;
				case 0x4:
					iva_dual_ir_empty_buffer(OMX_LEFT_IR_PORT_IDX,ISP_IR_LEFT_BUF_IDX_1);
				break;	
				case 0x8:
					iva_dual_ir_empty_buffer(OMX_LEFT_IR_PORT_IDX,ISP_IR_LEFT_BUF_IDX_2);
				break;	
				case 0x3:
					iva_dual_ir_empty_buffer(OMX_RIGHT_IR_PORT_IDX,ISP_IR_RIGHT_BUF_IDX_0);
				break;
				case 0x5:
					iva_dual_ir_empty_buffer(OMX_RIGHT_IR_PORT_IDX,ISP_IR_RIGHT_BUF_IDX_1);
				break;
				case 0x9:
					iva_dual_ir_empty_buffer(OMX_RIGHT_IR_PORT_IDX,ISP_IR_RIGHT_BUF_IDX_2);
				break;
				default:
				break;	
			}
		}
	}
}

void ifv_isp_cat_eye_interrupt_service()
{
	int mi_channel;
	LOGD(TAG, "enter cat eye interrupt!\n");
	while(1){
		ispReadIntFromIspRgb(&mi_channel);
		switch(mi_channel){
			case 0x2:
					iva_cat_eye_empty_buffer(0,0);
					//LOGD(TAG, "empty cat eye buffer0!\n");
			break;
			case 0x4:
					iva_cat_eye_empty_buffer(0,1);
					//LOGD(TAG, "empty cat eye buffer1!\n");
			break;
			case 0x8:
					iva_cat_eye_empty_buffer(0,2);
					//LOGD(TAG, "empty cat eye buffer2!\n");
			break;
			case 0x10:
					iva_cat_eye_empty_buffer(0,3);
					//LOGD(TAG, "empty cat eye buffer3!\n");
			break;
			case 0x20:
					iva_cat_eye_empty_buffer(0,4);
					//LOGD(TAG, "empty cat eye buffer4!\n");
			break;
			case 0x40:
					iva_cat_eye_empty_buffer(0,5);
					//LOGD(TAG, "empty cat eye buffer5!\n");
			break;
			default:
			break;
		}
	}
}

int if_vGetRegisterMode()
{
	return ifv_register_mode;
}

int if_vSetRegisterMode(int mode)
{
	ifv_register_mode = mode;
	return 0;
}

int ifv_ISP_cat_eye_interrupt_task_creat(void)
{
    int ret;
    ret = aos_task_new_ext(&g_ifv_ISP_cat_eye_task, "g_ifv_ISP_cat_eye_task", ifv_isp_cat_eye_interrupt_service, NULL, 10*1024, IFV_TASK_PRIO);
    if (ret) {
        return -1;
    }

    return 0;
}

int ifv_ISP_MI_interrupt_task_creat(void)
{
    int ret;
    ret = aos_task_new_ext(&g_ifv_ISP_task, "ifv_isp_int_task", ifv_isp_mi_interrupt_service, NULL, 10*1024, AOS_DEFAULT_APP_PRI);
    if (ret) {
        return -1;
    }

    return 0;
}

void jpg_pic_crop_AI_init(void)
{
    srcImgAddr = aos_malloc(3686400);// 1280*720*4 = 3686400, limit:720p for now!!!
    if (NULL== srcImgAddr){
        LOGD(TAG, "jpg_pic_crop_AI_init malloc failed\r\n");
    }
    LOGD(TAG, "jpg_pic_crop_AI_init malloc success\r\n");

    g_resize_pic = (char*)aos_malloc(CROP_PIC_WIDTH * CROP_PIC_HIGHT * 4);
    if (NULL == g_resize_pic)
    {
        LOGD(TAG, "[%s %d] Failed to allocate memory\r\n", __func__, __LINE__);
    }
}

int jpg_pic_crop_AI(if_v_register * register_info)
{
    int result = 0;
	int srcW = 0;
	int srcH = 0;
	float w,h = 0;

	tsmImg_t srcImg;
	tsmImg_t dstImg;
    int ret=0;

#if 1
    #if JPEG_CROP_MALLOC_ALL_TIME
    srcImg.data = srcImgAddr;// 1280*720*4 = 3686400, limit:720p for now!!!
    #else
    srcImg.data = malloc(3686400);// 1280*720*4 = 3686400, limit:720p for now!!!
    if (NULL == srcImg.data)
    {
        LOGD(TAG, "jpg_pic_crop_AI srcImg buffer malloc err \n");
        return -1;
    };
    #endif

	
	LOGD(TAG, "enter %s:%d size:%d \n", __FUNCTION__,__LINE__,register_info->pic_size);
    //jpg 2 raw rgb
    //result = jpeg_to_raw(register_info->buff, register_info->pic_size, DST_PIC_ADR, &srcW, &srcH, EXT_RGBA);
    //result = jpeg_to_raw(SRC_PIC_ADR, SRC_PIC_SIZE, DST_PIC_ADR, &srcW, &srcH, EXT_RGBA);
    result = jpeg_to_raw((char *)register_info->buff, register_info->pic_size, (char*)(srcImg.data), &srcW, &srcH, EXT_RGBA);
	LOGD(TAG, "enter %s:%d ret %d, srcW %d, srcH %d \n", __FUNCTION__,__LINE__,result, srcW,srcH);
    if(result < 0){
        if (NULL != srcImg.data) {
            #if JPEG_CROP_MALLOC_ALL_TIME
            #else
            if (NULL != srcImg.data)
            {
                LOGD(TAG, "jpg_pic_crop_AI srcImg buffer free  \n");
                free(srcImg.data);
            };
            #endif                                                  
        };
        
        return -1;
    }
        

    //LOGD(TAG, "convert done,width %d ,height %d \n", srcW, srcH);

    //check pic size
	result = checkPicSize(srcW, srcH, CROP_PIC_WIDTH, CROP_PIC_HIGHT, &w, &h);
	//LOGD(TAG, "enter %s:%d ret %d, w %f, h %f \n", __FUNCTION__,__LINE__,result, w, h);
#endif

#if 1
	srcImg.w = srcW;
	srcImg.h = srcH;
	srcImg.bits = 32;
	//srcImg.data = DST_PIC_ADR;

	dstImg.w = CROP_PIC_WIDTH;
	dstImg.h = CROP_PIC_HIGHT;
	dstImg.bits = 32;
	dstImg.data = g_resize_pic;

	//LOGD(TAG, "resize begin:result %d \n", result);
    
	aos_mutex_lock(&g_aie_mutex, AOS_WAIT_FOREVER);
	if(1 == result)
	{
		dstImg.h = srcH * w;
		//LOGD(TAG, "resizeDstH %d \n", srcH * w);
		ret = TSM_ALGO_RunAmrResize(&srcImg, &dstImg);

		srcW = 360;
		srcH = dstImg.h;
	}
	else if(2 == result)
	{
		dstImg.w = srcW * h;
		//LOGD(TAG, "resizeDstW %d \n", srcW * h);
		ret = TSM_ALGO_RunAmrResize(&srcImg, &dstImg);

		srcW = dstImg.w;
		srcH = 640;
	}
    
	aos_mutex_unlock(&g_aie_mutex);
	//LOGD(TAG, "resize done \n");

    #if JPEG_CROP_MALLOC_ALL_TIME
    srcImg.data = NULL;
    #else
    if (NULL != srcImg.data)
    {
        //LOGD(TAG, "jpg_pic_crop_AI srcImg buffer free  \n");
        free(srcImg.data);
    };
    #endif

    
#endif


#if 1
	//LOGD(TAG, "fillPicEdge begin \n");
//	fillPicEdge(RESIZE_PIC_ADR, DST_PIC_360x640_ADR, srcW, srcH, dstW, dstH, 0);
	fillPicEdge((uint32_t *)g_resize_pic, (uint32_t *)g_ifv_pic_register, srcW, srcH, CROP_PIC_WIDTH, CROP_PIC_HIGHT, 0);
	//LOGD(TAG, "fillPicEdge done \n");
#endif

    return ret;
}

bool if_vRegister(if_v_register * register_info)
{
    int ret=0;

	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_register_cmd;	
	cmd2openmax_list *cmd2openmax_recog = &g_ifv2openmax_recognize_cmd;
	
	ifv_printf(IFV_MSG_INFO," %s reg state %d [%ld] \r\n", __func__,cmd2openmax->state,aos_now_ms());
	if((cmd2openmax->state != APP2IFV_CMD_STATE_NONE) &&
		(cmd2openmax->state != APP2IFV_REGISTER_CMD_STATE_COMPLETE) ){
            ifv_printf(IFV_MSG_ERROR," %s %d reg state error %d \r\n", __func__, __LINE__, cmd2openmax->state);
			return 1;
     }

	//check if there recognize cmd,
	//wait recognize stop
	startRegisterCmd = 1;
	while( (cmd2openmax_recog->state != APP2IFV_CMD_STATE_NONE ) && 
		(cmd2openmax_recog->state != APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE ) ){

		ifv_printf(IFV_MSG_INFO," %s recognize state %d \r\n", __func__,cmd2openmax_recog->state );
		aos_msleep(100);

	}

	ifv_printf(IFV_MSG_INFO," do register \r\n");
    cmd2openmax->state = APP2IFV_REGISTER_CMD_STATE_INIT;
	//check the register info JPEG
	if(register_info && register_info->buff )
	{	
		//add to list
		//cmd2openmaxJpeg_list *cmd2openmaxjpeg = &g_ifv2openmax_jpeg_register_cmd;

		//cmd2openmaxjpeg->flag = 1;
		//cmd2openmaxjpeg->jpeg_reg_info.buff = register_info->buff;
		//list_add_tail(&cmd2openmaxjpeg->linked_list , &g_ifv2openmax_jpeg_register_cmd_list);
		//aos_sem_signal((aos_sem_t *)&ifvJpegRegisterSem);
        
        if (IFV_REGISTER_MODE_PIC_RAW == register_info->pic_mode)
        {
            memcpy(g_ifv_pic_register, register_info->buff, register_info->pic_size);
        }
        else if (IFV_REGISTER_MODE_PIC_JPG == register_info->pic_mode)
        {
            // long long t1=aos_now_ms();
            //ret = jpeg_2_rgba(register_info->buff,register_info->pic_size ,IFV_PIC_REGISTER_ADR_TEMP);
            ret = jpg_pic_crop_AI(register_info);
            if(ret < 0){
                cmd2openmax->state = APP2IFV_REGISTER_CMD_STATE_COMPLETE;
				startRegisterCmd = 0;
                ifv_printf(IFV_MSG_ERROR," %s %d reg state error %d \r\n", __func__, __LINE__, cmd2openmax->state);
                return 1;
            }
            // long long t2=aos_now_ms();
            //LOGD(TAG, "jpeg_2_rgba cost=%lld ms\n", t2-t1);
        }else{

        }
		ifv_register_mode=IFV_REGISTER_MODE_PIC_JPG;
        
        ifv_start_time = aos_now_ms();
        //LOGD(TAG, "@OUT reco=%lld\n", ifv_start_time);
        if_vNotifyVisIspData(1);
        
		//omx_register_from_IFV(register_info->buff, register_info->pic_size);
		//omx_register_from_IFV(NULL, 0);
	}else{
        tsmImg_t srcImg;
        tsmImg_t dstImg;
        extern aos_mutex_t g_aie_mutex;
        
        srcImg.w = 720;
        srcImg.h = 1280;
        srcImg.bits = 32;
        srcImg.data = (void *)MM_MIPI2DMA_BUF1;
    
        dstImg.w = 360;
        dstImg.h = 640;
        dstImg.bits = 32;
        dstImg.data = g_ifv_pic_register;


        aos_mutex_lock(&g_aie_mutex, AOS_WAIT_FOREVER);
        ret = TSM_ALGO_RunAmrResize(&srcImg, &dstImg);
         aos_mutex_unlock(&g_aie_mutex);
    
        ifv_register_mode=IFV_REGISTER_MODE_PIC_JPG;
		g_rgbSensorCapMode=1;
#if defined (MINI_STRUCTURE_LIGHT_MODULE)
        if_vNotifyVisIspData(1);
		g_rgbSensorCapMode=0;
#endif
	}
	return ret;
}

bool if_vQuery(if_v_query * query_info)
{
	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);
	
	return 0;
}

bool if_vDelete(if_v_query * delete_info)
{
	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);
	
	return 0;
}

int if_vDel(int id)
{
	int retval = 0;

	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);

	if(g_ifv_flow_cfg.sensetime_protocol_enable){
		retval = user_face_manage_ff_delete(id);
	}else{
		retval = tsm_ff_delete(id);
	}
	
	return retval;
}

int if_vDelRange(uint16_t idS, uint16_t idE)
{
	int ret = false;
	uint16_t i = 0;

	ifv_printf(IFV_MSG_ERROR,"===== %s =====, %d %d \r\n", __func__, idS, idE);

	if(idS > idE)
		return -1;

	for(i=idS; i<=idE; i++)
	{
		ret += if_vDel(i);
	}

	return ret;
}

int if_vDelAll(void)
{
	int32_t retval = 0;

	ifv_printf(IFV_MSG_INFO,"===== %s =====\r\n", __func__);

	if(g_ifv_flow_cfg.sensetime_protocol_enable){
		retval = user_face_manage_ff_clear();
	}else{
		retval = tsm_ff_clear();
	}

    if (0 > retval)
    {	
		delAllResultAck(1);
        ifv_printf(IFV_MSG_ERROR,"Failed to clear all id \r\n", __func__);
    }
    else
    {
		delAllResultAck(0);
        ifv_printf(IFV_MSG_ERROR,"Success to clear all id \r\n", __func__); 
    }

	return 0;
}

bool if_vGetUsrInfo(uint16_t user_id)
{
	uint8_t user_name[32] = {0};
	uint8_t admin;
	int ret = 0;
		 
	ret = get_user_info_by_id(user_id, user_name, &admin);
	if(ret){
		LOGD(TAG, "get user info error!");
	}
	else
		MsgGetUserInfoReply(user_id, user_name, admin, ret);
	return 0;
}


bool if_vGetAllUsrID(void)
{
	uint32_t usrIdCount = 0;
	uint16_t *idList = NULL;

	usrIdCount = user_face_manage_ff_num();
	if(usrIdCount){
		idList = aos_malloc(usrIdCount);
		if(idList){
			user_face_manage_ff_list(idList);
			MsgGetAllUserId(usrIdCount, (uint8_t *)idList, 0);
		}	
	}
	else
		MsgGetAllUserId(0, NULL, 0);

	if(idList)
		aos_free(idList);
		
	return 0;
}

bool if_vSetThreshLevel(uint32_t match_thresh, uint32_t living_thresh)
{

	MsgNoDataReply(0xD4,0);
	return 0;	
}

void if_vRecogIrSemaPost(int result)
{

	aos_sem_signal((aos_sem_t *)&ifvRecongIrSemp);

}


int ifvCmd2OpenmaxLookup(int list_type, int *cmd)
{
	cmd2openmax_list *cmd_node = NULL;

	if(APP2IFV_REGISTER_CMD == list_type){		
	// cmd2openmax_list *cmd2openmax = &g_ifv2openmax_register_cmd;
    dlist_for_each_entry(&g_ifv2openmax_register_cmd_list, cmd_node, cmd2openmax_list , linked_list) {
		if(cmd_node->flag){
			*cmd = cmd_node->cmd_type;
			ifv_printf(IFV_MSG_INFO," %s register request cmd %d\r\n", __func__, *cmd);			
			list_del((list_t *)&cmd_node->linked_list);
			return 1;
		}
	}
	}else if(APP2IFV_RECOGNIZE_CMD == list_type){		
		// cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
		dlist_for_each_entry(&g_ifv2openmax_recognize_cmd_list, cmd_node, cmd2openmax_list , linked_list){ 
			if(cmd_node->flag){
			*cmd = cmd_node->cmd_type;	
			ifv_printf(IFV_MSG_INFO," %s recognize cmd %d \r\n", __func__, *cmd);
				list_del((list_t *)&cmd_node->linked_list);
				return 1;
			}
		}
	}
	//ifv_printf(IFV_MSG_DEBUG,"===== %s return none=====\r\n", __func__);
	return APP2IFV_CMD_STATE_NONE;
}


int cmd2Openmax_wait_sema(int timeout)
{
	return aos_sem_wait((aos_sem_t *)&ifvCmd2OpenmaxSemp, timeout == 0 ? AOS_WAIT_FOREVER:timeout);
}
void cmd2Openmax_post_sema()
{	
	aos_sem_signal((aos_sem_t *)&ifvCmd2OpenmaxSemp);
}

void if_vRecognition_process(unsigned char * card_number, app2if_v_cb *info,  int timeout)
{
	int ret=0; 
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	cmd2openmax_list *cmd2openmax_reg = &g_ifv2openmax_register_cmd;	

	ifv_printf(IFV_MSG_INFO,"Enter %s state %d\r\n", __func__, cmd2openmax->state);
    	
	if( (cmd2openmax->state != APP2IFV_CMD_STATE_NONE ) 
		&& (cmd2openmax->state != APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE))
	{
		ifv_printf(IFV_MSG_INFO," %s recogn state %d return.\r\n", __func__,cmd2openmax->state );
		return;	
	}
    tRecogizeStart = aos_now_ms();

    if(cmd2openmax_reg->state == APP2IFV_REGISTER_CMD_STATE_INIT)   return;
        
	memset(cmd2openmax,0,sizeof(cmd2openmax_list));

	ifv_printf(IFV_MSG_INFO," do %s\r\n", __func__);

	if ((g_ifv_flow_cfg.source_ir_left) && (!g_ifv_flow_cfg.source_ir_right))
	{
		clearAEConvergentStatus();
        cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY;
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_IR;
		irreco_enable_flag = 1;
        if(irreco_exp_init_done == 0)
        {
            ifv_setIspexp(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            //ifv_setIspSetPoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            irreco_exp_init_done = 1;
        }
		qw_isp_ae_lock_judge_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
        qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
		if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
		
        ifv_printf(IFV_MSG_INFO,"%s %d wait rece IR done event.\n", __func__, __LINE__); 
        //wiat ir callback event done, which to deal with cmd spk. 
        ret = cmd2Openmax_wait_sema(3000);
        if(RHINO_SUCCESS == ret)
            ifv_printf(IFV_MSG_INFO,"%s IR done, and resume SPK led .\n", __func__);    
        else{
            ifv_printf(IFV_MSG_ERROR,"%s IR Error %d.\n",__func__,ret);
            if_vFlowStateReset(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            return ;
        };
	}
	else if (g_ifv_flow_cfg.source_ir_tof)
	{
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY;
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_IR;
		if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
		
        ifv_printf(IFV_MSG_INFO,"%s %d wait rece IR done event.\n", __func__, __LINE__); 
        //wiat ir callback event done, which to deal with cmd spk. 
        ret = cmd2Openmax_wait_sema(3000);
        if(RHINO_SUCCESS == ret)
            ifv_printf(IFV_MSG_INFO,"%s IR done, and resume SPK led .\n", __func__);    
        else{
            ifv_printf(IFV_MSG_ERROR,"%s IR Error %d.\n",__func__,ret);
            if_vFlowStateReset(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            return ;
        };
	}
	else if ((g_ifv_flow_cfg.source_ir_left) && (g_ifv_flow_cfg.source_ir_right))
	{
		if (!(mipiWorkStatusFlag & (1 << 1)) && (mipiWorkStatusFlag & (1 << 4))) //if work on rgb and couldn't change mode,return
        {
			enroll_from_uart_busy_flag = 0;
			enroll_or_recognize_busy_flag = 0;
            return;
        }
        clearAEConvergentStatus();
		cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_IR_ENTRY;
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_IR;
		irreco_enable_flag = 1;
        if(irreco_exp_init_done == 0)
        {
            ifv_setIspexp(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            ifv_setIspexp(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
            //ifv_setIspSetPoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            //ifv_setIspSetPoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
            irreco_exp_init_done = 1;
        }
		qw_isp_ae_lock_judge_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
		qw_isp_ae_lock_judge_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, true);
        qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
        qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, true);
		if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap

		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type = LED_LIGHT_TYPE_IR;
        if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].mipi_id, \
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, \
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type);
        
        aos_timer_start(&g_double_ir_mi_rx_timer);
		
		return;
	}
#if 0	
   if (g_ifv_flow_cfg.source_ir_right)
   {
       cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_RIGHT_IR_ENTRY;
       TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type = LED_LIGHT_TYPE_IR;
           if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
               TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].mipi_id, \
               TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, \
               TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type);
           
       ifv_printf(IFV_MSG_INFO,"%s %d wait rece IR done event.\n", __func__, __LINE__); 
       //wiat ir callback event done, which to deal with cmd spk. 
       ret = cmd2Openmax_wait_sema(3000);
       if(RHINO_SUCCESS == ret)
           ifv_printf(IFV_MSG_INFO,"%s IR done, and resume SPK led .\n", __func__);    
       else{
           ifv_printf(IFV_MSG_ERROR,"%s IR Error %d.\n",__func__,ret);
           if_vFlowStateReset(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
           return ;
       };
   }
#endif
    if (g_ifv_flow_cfg.source_spk)
    {
        cmd2openmax->cmd_type = VIDEO_SRC02_MODE_SPECKLE;
        cmd2openmax->flag = 1;  
    	cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_SPK_ENTRY;
        g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 1;
        
    	//resume
    	TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_SPK;

        /* Begin: Added for static speckle expo by yangguangjun on 20201126 */
        // regval_list ir_expo_arg[] = { 
        //     {0x3501,0x0},   //expo H		
        //     {0x3502,0x0},   //expo L
    	// 	{0x3508,0x0},	//gain
        //     {0x3509,0x0},   //gain
    	// 	{0x3927,0x0}, 
        //     {0x3928,0x0},   //width
        //     {0x3929,0x0},   //strobe expo
        //     {0x392a,0x0},   //strobe expo
        // };
        if (g_ifv_sensor_func.pGetExpoPara)
        {
            g_ifv_sensor_func.pGetExpoPara();
        }

        if (g_ifv_sensor_func.pSetExpoPara)
        {
            g_ifv_sensor_func.pSetSpkStrobePara();
        }
        qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, false);
		qw_isp_ae_lock_judge_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, false);
		g_irSensorConvergent[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id] = 1;
    	if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME, \
    		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, \
    		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, \
    		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); //new_cap
    	ifv_printf(IFV_MSG_INFO,"%s wait recv SPK done event.\n", __func__);	
    	//wait openmax get spk frame end
    	ret = cmd2Openmax_wait_sema(3000);
        /* Begin: Added for static speckle expo by yangguangjun on 20201126 */
        if (g_ifv_sensor_func.pSetExpoPara)
        {
            g_ifv_sensor_func.pSetExpoPara();
        }
		qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
    	if(RHINO_SUCCESS == ret)
    		ifv_printf(IFV_MSG_INFO,"%s Get SPK OK~~~~\n",__func__);
    	else{
    		ifv_printf(IFV_MSG_ERROR,"%s SPK Error %d.\n",__func__,ret);
    		if_vFlowStateReset(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
    		//fake interrupt to openmax
    		if_vNotifyIspSpkData();
    		return ;
    	};    
    }

	cmd2openmax->state = APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE;
    return;
    
}

void if_v_service_event(input_event_t *event, void *priv_data)
{
	ifv_printf(IFV_MSG_INFO," %s code %d \r\n", __func__,event->code);

    if (event->type != EV_IFV) {
        return;
    }

}


//app send cmd to if.v
int ifv_post_msg(ifv_msg_pkg_t msg)
{
    if(APP2IFV_REGISTER_CMD_BATCH_START == if_vGet_RunningState()){
        ifv_printf(IFV_MSG_INFO," %s batch register... \r\n", __func__);
    }else{
        int ret;
        ret = aos_queue_send(&g_ifv_queue, (void *)&msg, sizeof(msg));
        if (ret) {		
        	ifv_printf(IFV_MSG_ERROR," %s ret %d \r\n", __func__,ret);
        	return -1;
        }
    }
    return 0;
}

bool if_vSensorLedControl(int sensorID, int led_type) //ir/spk
{
    TSM_VI_INFO_S stViInfo = {0};
	
	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);


	tsm_vi_pause(&stViInfo);
	
	aos_msleep(100);
	
	if (SNAPSHOT_MODE_3IN1_VIS_IR == g_snapshot_3in1_m)
	{
		stViInfo.stLedInfo.enLightType	= LED_LIGHT_TYPE_SPK;
		g_snapshot_3in1_m = SNAPSHOT_MODE_3IN1_SPK;
		
		ifv_printf(IFV_MSG_INFO," %s led IR>SPK \r\n", __func__);
	}
	else if (SNAPSHOT_MODE_3IN1_SPK == g_snapshot_3in1_m)
	{
		stViInfo.stLedInfo.enLightType	= LED_LIGHT_TYPE_IR;
		g_snapshot_3in1_m = SNAPSHOT_MODE_3IN1_VIS_IR;
		
		ifv_printf(IFV_MSG_INFO," %s led SPK>IR \r\n", __func__);
	}
	stViInfo.stSnsInfo.u32Expo		= SENSOR_EXPO_INDOOR;
	tsm_vi_resume(&stViInfo);
	return true;
}


bool if_vFaceRecogEvent(int sensorID, void *pData)
{
	TsmFaceFeatrue *pFeature = NULL;
	TsmFaceResult *tp = NULL;
	
	ifv_printf(IFV_MSG_INFO," %s register %d=\n", __func__, register_flag);
	//do recongnize callback 
	ifv_printf(IFV_MSG_INFO," sensor id %d, feature len %d , faceNum %d =\n", sensorID, ((TsmFaceResult *)pData)->feature.len, ((TsmFaceResult *)pData)->nFace );
	
	if(register_flag){
		register_flag = 0;
		//save feature
		pFeature = &((TsmFaceResult *)pData)->feature;
		tp = (TsmFaceResult *)pData;
		
		if(totalFaceNum == curFaceNum)
		{
			if(curOffset == FACE_FEATURE_SIZE*2*totalFaceNum)
			{
				curOffset = 0;
				curFaceID = 1;
			}
			else
			{
				curFaceID += tp->nFace;
			}
		}
		else
		{
			curFaceNum += tp->nFace;
			curFaceID += tp->nFace;
		}
		LOGD(TAG, "curFaceNumber %d,curOffset %d,id %d \n",curFaceNum,curOffset,curFaceID);
		//memcpy(msg_buf+1,(uint8_t *)&curFaceID,4);				
		//msg.len = 5;
		pFeature = &tp->feature;
		memcpy(faceFeature+curOffset,pFeature->vector,tp->nFace*pFeature->len*sizeof(int16_t));
		curOffset += FACE_FEATURE_SIZE*2;
		//aie_update_feature(faceHd,curFaceNum,faceFeature);
	}
	ifv_stop_time = aos_now_ms();
	//LOGD(TAG, "@OUT reco=%d\n", ifv_stop_time);
	return true;
}

bool if_v3DdetectEvent(int sensorID, void *pData)
{
	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);
	//ifvSetCapturePicMode2Openmax(1,VIDEO_SRC03_MODE_NONE);
	return true;
}

bool if_vVisDetectEvent(int event, void *pData)
{
	//ifv_printf(IFV_MSG_INFO,"===== %s pData 0x%x=====\r\n", __func__, pData);
	if(0 == aie_vis_detect_enable && aie_vis_reco_enable == 0)
	{
		lv_clear_frame();
		return 0;
	}
	
	if(pData == NULL)
		return 0;
	//LOGD(TAG, "%s %p \n", __func__, pData);
	TsmFaceResult *tp  = (TsmFaceResult *)pData;
#if 0
	for(int i=0;i<tp->nFace;i++)
	{
		TsmFaceBox *pBox = (tp->box + i);
		int16_t xmin = (int16_t)((360*pBox->xmin) - 60);
		int16_t xmax = (int16_t)((360*pBox->xmax) - 60);
		int16_t ymin = (int16_t)((640*pBox->ymin) - 140);
		int16_t ymax = (int16_t)((640*pBox->ymax) - 140);
		
		//LOGD(TAG, "vis face : xmin :%d, xmax :%d, ymin :%d, ymax :%d \n", xmin, xmax, ymin, ymax);
			
		lv_draw_frame_by_line(xmin, xmax, ymin, ymax);	
		
		//lv_draw_frame_by_line(10, 120, 10, 160);	
	}
	if(tp->nFace == 0)
		lv_clear_frame();
	
	if(0 == aie_vis_detect_enable)
	{
		lv_clear_frame();
	}
#endif

    //LOGD(TAG, "if_vVisDetectEvent nFace: %d\r\n", tp->nFace);
	if(tp->nFace > 0)
    {

	// UI_RECOGNIZE_FAIED = 0,
    // UI_RECOGNIZE_SUCCESS = 1,
    // UI_FACE_DETECTED = 2,
    // UI_FACE_STADBY = 3,
        //send_ui_msg(2);
        //aos_timer_stop(&timer_gui_idle);  
        //aos_timer_start(&timer_gui_idle);  
		
		if(aie_vis_reco_enable)
			vis_reco_event(tp);
    }
	    
	return 0;
}

int if_vReadDataFromVis_ISP(int outType)//rgb
{
	ifv_printf(IFV_MSG_INFO," %s wait ISP1\r\n", __func__);
	aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp_rgb, AOS_WAIT_FOREVER);
	//outType = ifvDataSemp_isp1.type;
	ifv_printf(IFV_MSG_INFO," %s Get ISP1 %d\r\n", __func__,outType);
	return 0;
}


int if_vReadIrSpkDataFromISP()
{
	ifv_printf(IFV_MSG_DEBUG," %s wait ISP ir/spk data\r\n", __func__ );
	aos_sem_wait((aos_sem_t *)&ifvDataIrSpkSemp_isp, AOS_WAIT_FOREVER);		
	ifv_printf(IFV_MSG_DEBUG," %s Get ISP ir/spk data\r\n", __func__ );


	return 1;
}

int if_vNoifyIrSpkData(int isp_id)
{
	ifv_printf(IFV_MSG_DEBUG," %s Signal ISP ir/spk data\r\n", __func__ );
	aos_sem_signal((aos_sem_t *)&ifvDataIrSpkSemp_isp);

	return 1;
}

int if_vReadSnapDataFromISP(int outType)
{
	ifv_printf(IFV_MSG_DEBUG," %s wait ISP data\r\n", __func__ );
	aos_sem_wait((aos_sem_t *)&ifvSnapDataSemp_isp, AOS_WAIT_FOREVER);

	ifv_printf(IFV_MSG_DEBUG," %s get ISP data \r\n", __func__ );	

	return 1;
}

void if_vNotifyIspSnapData(int isp_id)
{
	ifv_printf(IFV_MSG_INFO," %s post ISP%d data\r\n", __func__,isp_id);
		aos_sem_signal((aos_sem_t *)&ifvSnapDataSemp_isp);
	return;
}

#if 1 //DOUBLE_IR_ENABLE
void if_vNotifyIspMiData(int isp_id)
{
	ifv_printf(IFV_MSG_INFO,"========= %s post ISP%d data=========\r\n", __func__,isp_id);
	if(ISP_0 == isp_id)
		aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp0_mi0);
	else if(ISP_1 == isp_id)
		aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp1_mi0);
	else if(ISP_2 == isp_id)
		aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp2_mi0);
	else
		LOGD(TAG, "error isp id \n");

	ifv_printf(IFV_MSG_INFO,"========= %s post ISP%d data over=========\r\n", __func__,isp_id);

}

int if_vReadIspMiData(int isp_id)
{
	int ret = 0;
	ifv_printf(IFV_MSG_INFO,"========= %s wait ISP%d data=========\r\n", __func__,isp_id);
	if(ISP_0 == isp_id)
		ret = aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp0_mi0, AOS_WAIT_FOREVER);
	else if(ISP_1 == isp_id)
		ret = aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp1_mi0, AOS_WAIT_FOREVER);
	else if(ISP_2 == isp_id)
		ret = aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp2_mi0, AOS_WAIT_FOREVER);
	else
		LOGD(TAG, "error isp id \n");

	ifv_printf(IFV_MSG_INFO,"========= %s Got ISP%d data=========\r\n", __func__,isp_id);

	return ret;
}

#endif

int if_vReadDataFromISPIr(int outType)//ir
{
	ifv_printf(IFV_MSG_INFO," %s wait ISP-IR data\r\n", __func__ );
	aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp_ir, AOS_WAIT_FOREVER);
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	ifv_printf(IFV_MSG_INFO," %s get ISP-IR data, recogn state %d \r\n", __func__, cmd2openmax->state );	
	if(cmd2openmax->state == APP2IFV_CMD_STATE_NONE)
		return 0;

	return 1;
}


void if_vNotifyIspIrData()
{
	aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp_ir);
}


int if_vReadDataFromISPSpk(int outType)//ir
{
	ifv_printf(IFV_MSG_INFO," %s wait ISP-SPK data\r\n", __func__ );
		aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp_spk, AOS_WAIT_FOREVER);
		cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	ifv_printf(IFV_MSG_INFO," %s get ISP-SPK data, recogn state %d \r\n", __func__, cmd2openmax->state );	
		if(cmd2openmax->state == APP2IFV_CMD_STATE_NONE)
			return 0;

	return 1;
}


void if_vNotifyIspSpkData()
{
	aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp_spk);
}


int if_vReadDataFromISP(int isp_id, int *outType)
{
	ifv_printf(IFV_MSG_INFO," %s wait ISP%d data\r\n", __func__, isp_id);
	if(isp_id == ISP_RGB_ID){
		aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp_rgb, AOS_WAIT_FOREVER);
		//*outType = ifvDataSemp_isp0.type;
	}else if(isp_id == ISP_IR_ID)
	{
		//aos_sem_wait((aos_sem_t *)&ifvDataSemp_isp1, AOS_WAIT_FOREVER);
		//*outType = ifvDataSemp_isp1.type;
	}else{};
	ifv_printf(IFV_MSG_DEBUG," %s Get ISP%d data %d\r\n", __func__, isp_id,*outType);
		
	//after read data, standby the isp.
	//if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,MIPI_1, ISP_1, LED_LIGHT_TYPE_SPK);
	return 0;
}


void if_vNotifyVisIspData(int isp_id)
{
	ifv_printf(IFV_MSG_INFO,"=== %s post ISP%d data ===\r\n", __func__,isp_id);
	aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp_rgb);
	//else if(isp_id == ISP_IR_ID)
	//	aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp1);
	//else{};
}

void if_vNotifyIspData(int isp_id)
{
	//ifv_printf(IFV_MSG_INFO,"========= %s post ISP%d data=========\r\n", __func__,isp_id);
	if(isp_id == ISP_RGB_ID)	
		aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp0);
	//else if(isp_id == ISP_IR_ID)
	//	aos_sem_signal((aos_sem_t *)&ifvDataSemp_isp1);
	else{};
}


int if_vIrStreamPauseResume(int action, int mipi_id, int isp_id, int led_type)
{
    TSM_VI_INFO_S stViInfo = {0};
 //   static uint32_t g_snapshot_3in1_m = SNAPSHOT_MODE_3IN1_VIS_IR;

	stViInfo.stSnsInfo.u32MipiId	= mipi_id;	//MIPI_2;
	stViInfo.stPipeInfo.u32PipeId	= isp_id; 	//ISP_1;
	stViInfo.stLedInfo.enLightType	= led_type;	//LED_LIGHT_TYPE_IR;
	stViInfo.stLedInfo.u32DelayTime = (uint32_t)(isp_instance[TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id].ae_integr * 1000);
	//stViInfo.stSnsInfo.u32Expo		= TX510_IR_defConfig.scenario_type;// SENSOR_EXPO_INDOOR;
	//ifv_printf(IFV_MSG_INFO," %s %s mipi%d, isp%d led_type %d, Expo %d \n",__func__,action == 0?"pause":"resume", mipi_id,isp_id, led_type,stViInfo.stSnsInfo.u32Expo);
	//ifv_printf(IFV_MSG_ERROR, " %s %s\n", __func__,action == 0?"pause":"resume");
	if(action == 0)			//pause
	{
		tsm_vi_pause(&stViInfo);
	}
	else if(action == 1)	//resume
	{	
		tsm_vi_resume(&stViInfo);
	}
	return 0;
}


int if_vRgbStreamPauseResume(int action )
{
    TSM_VI_INFO_S stViInfo = {0};
	int mipi_id = MIPI_1; 
	int isp_id =  ISP_1;
	int led_type = LED_LIGHT_TYPE_RGB;

	stViInfo.stSnsInfo.u32MipiId	= mipi_id;	
	stViInfo.stPipeInfo.u32PipeId	= isp_id; 	
	stViInfo.stLedInfo.enLightType	= led_type;
	stViInfo.stSnsInfo.u32Expo		= TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].scenario_type;

	ifv_printf(IFV_MSG_INFO," %s %s mipi%d, isp%d led_type %d, Expo %d \n",__func__,action == 0?"pause":"resume", mipi_id,isp_id, led_type,stViInfo.stSnsInfo.u32Expo);
	if(action == 0)			//pause
	{		
		// void *target = MM_IMG_RGB_BUF0;
		tsm_vi_pause(&stViInfo);		
		// memset(target, 0,640*360*4);
	}
	else if(action == 1)	//resume
	{	
		tsm_vi_resume(&stViInfo);
	}
	return 0;
}


void ifv_debug_print_timestamp(void)
{
	struct timeval tv;

	gettimeofday(&tv, NULL);
	LOGD(TAG, "%ld.%06u: ", (long) tv.tv_sec, (unsigned int) tv.tv_usec);
}


void ifv_printf(int level, const char *fmt, ...)
{
	if (level >= ifv_debug_level) {
		va_list ap;

		va_start(ap, fmt);
	
		ifv_debug_print_timestamp();
		vprintf(fmt, ap);
		// LOGD(TAG, "\n");
		va_end(ap);
	}
}

#define ISP_EXP_GRID_ITEMS	25
typedef uint8_t MeanLuma_t[ISP_EXP_GRID_ITEMS];
static float aec_mean_luma( const MeanLuma_t luma )
{
    float sum = 0.0f;
    int32_t i;

    for ( i = 0U; i < ISP_EXP_GRID_ITEMS; i++ )
    	sum += (float)((uint32_t)luma[i]);

    return ( sum / ISP_EXP_GRID_ITEMS );
}

void if_vGetMeanluma(int32_t idx, uint32_t *MeanLuma)
{
	MeanLuma_t aec_exp_means = {0};
    
	//1. calc image mean luma
	aec_exp_means[0] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_00);
	aec_exp_means[1] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_10);
	aec_exp_means[2] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_20);
	aec_exp_means[3] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_30);
	aec_exp_means[4] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_40);

	aec_exp_means[5] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_01);
	aec_exp_means[6] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_11);
	aec_exp_means[7] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_21);
	aec_exp_means[8] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_31);
	aec_exp_means[9] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_41);

	aec_exp_means[10] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_02);
	aec_exp_means[11] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_12);
	aec_exp_means[12] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_22);
	aec_exp_means[13] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_32);
	aec_exp_means[14] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_42);

	aec_exp_means[15] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_03);
	aec_exp_means[16] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_13);
	aec_exp_means[17] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_23);
	aec_exp_means[18] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_33);
	aec_exp_means[19] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_43);

	aec_exp_means[20] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_04);
	aec_exp_means[21] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_14);
	aec_exp_means[22] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_24);
	aec_exp_means[23] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_34);
	aec_exp_means[24] = (uint8_t)isp_reg_read(idx, ISP_EXP_MEAN_44);

	*MeanLuma = aec_mean_luma(aec_exp_means);
#if 0
    if (idx == 1)
    {
        return;
    }
    LOGD(TAG, "%s: ISP%d, mean_luma: %f\n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n\
    %02d, %02d, %02d, %02d, %02d \n",
    		__FUNCTION__, idx, *MeanLuma,
            aec_exp_means[CAMERIC_ISP_EXP_GRID_00],
            aec_exp_means[CAMERIC_ISP_EXP_GRID_10],
            aec_exp_means[CAMERIC_ISP_EXP_GRID_20],
            aec_exp_means[CAMERIC_ISP_EXP_GRID_30],
            aec_exp_means[CAMERIC_ISP_EXP_GRID_40],

			aec_exp_means[CAMERIC_ISP_EXP_GRID_01],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_11],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_21],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_31],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_41],

			aec_exp_means[CAMERIC_ISP_EXP_GRID_02],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_12],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_22],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_32],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_42],

			aec_exp_means[CAMERIC_ISP_EXP_GRID_03],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_13],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_23],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_33],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_43],

			aec_exp_means[CAMERIC_ISP_EXP_GRID_04],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_14],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_24],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_34],
			aec_exp_means[CAMERIC_ISP_EXP_GRID_44] );
#endif
}
#define IN2OUT_TRIGGER_CNT 7
int scene_judge_meanluma( int32_t idx, MeanLumaSceneJudgeConfig_s *cfg )
{
	uint32_t img_mean_luma = 0;
    static int32_t in2out_confirm_cnt = IN2OUT_TRIGGER_CNT;

	if (NULL == cfg)
		return -1;

	if_vGetMeanluma(idx, &img_mean_luma);
	LOGD(TAG, "img_mean_luma %d \n ",img_mean_luma);

	//2. judge current scene
	if(img_mean_luma < cfg->thd_max_h && img_mean_luma > cfg->thd_max_l)
    {
		LOGD(TAG, "in2out_confirm_cnt:[%d]\n", in2out_confirm_cnt);
        if (in2out_confirm_cnt <= 0)
        {
			LOGD(TAG, "change to outdoor\n");
            cfg->scene = SENSOR_EXPO_OUTDOOR;
            in2out_confirm_cnt = IN2OUT_TRIGGER_CNT;
        }
        else
        {
            in2out_confirm_cnt--;
        }
    }   
	else if (img_mean_luma < cfg->thd_min_h && img_mean_luma > cfg->thd_min_l)
    {
		LOGD(TAG, "change to indoor\n");
		cfg->scene = SENSOR_EXPO_INDOOR;
        in2out_confirm_cnt = IN2OUT_TRIGGER_CNT;
    }   
	else
		cfg->scene = SENSOR_EXPO_BUTT;

	return 0;
}
#if 0
//#define AE_EXPO_OUTDOOR_MAX 0.08
#define AE_EXPO_OUTDOOR_MAX 0.015
uint32_t g_expo_scene = SENSOR_EXPO_INDOOR;
float cis_ae_expo = 0.0f;
int scene_judge_expo()
{
	float cis_ae_gains = 0.0f;
	float cis_ae_integr = 0.0f;

    g_expo_scene = SENSOR_EXPO_INDOOR;
    
    cis_ae_expo_get(&cis_ae_gains, &cis_ae_integr);
    cis_ae_expo = cis_ae_gains * cis_ae_integr;
    if (cis_ae_expo < AE_EXPO_OUTDOOR_MAX)
    {
        g_expo_scene = SENSOR_EXPO_OUTDOOR;
    }
    
	return g_expo_scene;
}
#endif
int if_vReConfigSensorLed()
{	
	ifv_printf(IFV_MSG_INFO," %s \r\n", __func__);
	return 0;
}


void if_vIspBufferSetMap(int type)
{
	if(type == VIDEO_SRC03_MODE_IR)
		vi_isp_buffer_set(ISP_1, MI_SP_Y_BASE_AD, (uint32_t)g_fb_ir[g_fb_buffer_group_id]);
	else if(type == VIDEO_SRC03_MODE_SPECKLE)
		vi_isp_buffer_set(ISP_1, MI_SP_Y_BASE_AD, (uint32_t)g_fb_spk_left[g_fb_buffer_group_id]);
}


//for 9282 , 0, 0
void if_vGetIrSpkSnapShot(int mipi_id, int isp_id, int led_type, unsigned char *pBuffer)
{	
	int ret;

	if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,mipi_id, isp_id, led_type);

	if(LED_LIGHT_TYPE_IR == led_type){
		LOGD(TAG, "%s ir snapshot\n",__func__);
		
		//ret = if_vReadDataFromISP0(VIDEO_SRC02_MODE_IR);
		ret = if_vReadSnapDataFromISP(VIDEO_SRC02_MODE_IR);
	}
	else if(LED_LIGHT_TYPE_SPK == led_type){
		LOGD(TAG, "%s spk snapshot \n",__func__);
		
		//ret = if_vReadDataFromISP0(VIDEO_SRC02_MODE_SPECKLE);
		ret = if_vReadSnapDataFromISP(VIDEO_SRC02_MODE_SPECKLE);
	}

	const void *src = (const void *)MM_IMG_IR_BUF0;
	memcpy(pBuffer,src, 640*360);

	if_vIrStreamPauseResume(ISP_IR_STREAM_STANDBY,mipi_id, isp_id, led_type);

	if_vSet_RunningState(IFV_RUNNING_STATE_NONE);
	
}

//for 9732 , 0, 0
void if_vGetRGBSnapShot(unsigned char *pBuffer, int len)
{	
    isp_stop(1);
	memcpy(pBuffer, MM_MIPI2DMA_BUF1, len);
    isp_start(1);
    
	//if_vSet_RunningState(IFV_RUNNING_STATE_NONE);
}

int if_vThresRecoGet(float *thres)
{
    int ret = 0;
    int len = sizeof(float);
    
    ret = aos_kv_get(IFV_CLI_THRES_RECOG, thres, &len);
    if (ret != 0) 
    {
        *thres = g_ifv_flow_cfg.facematch_thres;
    }
    
    return ret;
}

int if_vThresRecoSet(float thres)
{
    int ret = 0;

    omx_thres_recog_set(thres);
    ret = aos_kv_set(IFV_CLI_THRES_RECOG, &thres, sizeof(thres), 1);
    if (ret != 0) 
    {
        LOGD(TAG, "Failed to set recog thres\r\n");
    }
    else
    {
        LOGD(TAG, "Success to set recog thres\r\n");
    }
    
    return ret;
}

int if_vThresRecoSetDefault()
{
    int ret = 0;

    omx_thres_recog_set(g_ifv_flow_cfg.facematch_thres);
    ret = aos_kv_del(IFV_CLI_THRES_RECOG);
    if (ret != 0) 
    {
        LOGD(TAG, "Failed to del recog thres\r\n");
    }
    else
    {
        LOGD(TAG, "Success to del recog thres\r\n");
    }
    
    return ret;
}

int if_vThresMaskRecoGet(float *thres)
{
    int ret = 0;
    int len = sizeof(float);
    
    ret = aos_kv_get(IFV_CLI_THRES_RECOG_MASK, thres, &len);
    if (ret != 0) 
    {
        *thres = FACE_PROC_THRES_DEF_RECOG_MASK;
    }
    
    return ret;
}

int if_vThresMaskRecoSet(float thres)
{
    int ret = 0;

    omx_thres_mask_recog_set(thres);
    ret = aos_kv_set(IFV_CLI_THRES_RECOG_MASK, &thres, sizeof(thres), 1);
    if (ret != 0) 
    {
        LOGD(TAG, "Failed to set mask recog thres\r\n");
    }
    else
    {
        LOGD(TAG, "Success to set mask recog thres\r\n");
    }
    
    return ret;
}

int if_vThresMaskRecoSetDefault()
{
    int ret = 0;

    omx_thres_mask_recog_set(FACE_PROC_THRES_DEF_RECOG_MASK);
    ret = aos_kv_del(IFV_CLI_THRES_RECOG_MASK);
    if (ret != 0) 
    {
        LOGD(TAG, "Failed to del mask recog thres\r\n");
    }
    else
    {
        LOGD(TAG, "Success to del mask recog thres\r\n");
    }
    
    return ret;
}

int if_vPreviewModeGet()
{
	int ret = 0;
	int len = sizeof(float);
	ret = aos_kv_get(IFV_UVC_PREVIEW_MODE, &g_uvc_preview_mode_enable, &len);
    if (ret != 0) 
    {
		g_uvc_preview_mode_enable = false;
        LOGD(TAG, "uvc preview mode is %d\n",g_uvc_preview_mode_enable);
    }
	else{
		LOGD(TAG, "uvc preview mode is %d\n",g_uvc_preview_mode_enable);
	}
	return 0;
}

int if_vAieThres2dSet(float thres)
{
    int ret = 0;
	//if_vSet_RunningState(APP2IFV_REGISTER_CMD_BATCH_START);
	tsmFaceProcessParam face_param; 
	aos_mutex_lock(&g_aie_mutex, AOS_WAIT_FOREVER);
	TSM_ALGO_GetFaceProcessParam(AIE_handle, &face_param);
	face_param.livingNirThres = thres;
    ret = TSM_ALGO_SetFaceProcessParam(AIE_handle, &face_param);
	aos_mutex_unlock(&g_aie_mutex);
    //if_vSet_RunningState(APP2IFV_REGISTER_CMD_BATCH_COMPLETE);
    if(ret != 0) {
		return ret;
	}

    return ret;
}

int if_vThres2dSet(float thres)
{
    int ret = 0;

    if_vAieThres2dSet(thres);
    ret = aos_kv_set(IFV_CLI_THRES_2D, &thres, sizeof(thres), 1);
    if (ret != 0) 
    {
        LOGD(TAG, "Failed to set 2d thres\r\n");
    }
    else
    {
        LOGD(TAG, "Success to set 2d thres\r\n");
    }

    return ret;
}

int if_vThres2dSetDefault()
{
    int ret = 0;
    
    if_vAieThres2dSet(FACE_PROC_THRES_DEF_2D);
    ret = aos_kv_del(IFV_CLI_THRES_2D);
    if (ret != 0) 
    {
        LOGD(TAG, "Failed to del 2d thres\r\n");
    }
    else
    {
        LOGD(TAG, "Success to del 2d thres\r\n");
    }
    
    return ret;
}

int if_vThres2dGet(float *thres)
{
    int ret = 0;
    int len = sizeof(float);
    
    ret = aos_kv_get(IFV_CLI_THRES_2D, thres, &len);
    if (ret != 0) 
    {
        *thres = FACE_PROC_THRES_DEF_2D;
    }
    
    return ret;
}

void timer_recog_ratelimit_cb(void *arg,void *arg2)
{
   g_recog_repeat_suppress = false;
}

int vis_image_channel_set(imageChannel_t *image_ch, bool isp_bypass, uint32_t i2c_num, uint32_t i2c_slave_addr)
{
	isp_sw_reset(image_ch->isp_ch);
	aos_msleep(3);
	mipi_config(image_ch);
	if (false == isp_bypass) 
	{
		CamEngineInstConfig_t cfg = {0};
		cfg.index               = (CamEngineInstIndex_t)image_ch->isp_ch;
        cfg.i2c_num             = i2c_num;
        cfg.i2c_slave_addr      = i2c_slave_addr;
        isp_res_map(image_ch->in.res, (uint32_t *)&cfg.mp_cfg.width, (uint32_t *)&cfg.mp_cfg.height);
        isp_res_map(image_ch->out.res, (uint32_t *)&cfg.sp_cfg.width, (uint32_t *)&cfg.sp_cfg.height);
        cfg.crop_cfg.width = image_ch->crop_res_x;
        cfg.crop_cfg.height = image_ch->crop_res_y;
		if(image_ch->out.format == ARGB)
			cfg.sp_cfg.mode = CAMERIC_MI_DATAMODE_RGB888;
		else if(image_ch->out.format == YUV422)
			cfg.sp_cfg.mode = CAMERIC_MI_DATAMODE_YUV422;
        cfg.camEngineType = ISP_ENGINE_RGB;

        isp_format_map(image_ch->in.format, &cfg.inputSelection);

		IspEngineConfigStart(cfg.index, &cfg);
//		CamIrStartStreaming(cfg.index);
		CamIrStartStreaming(&cfg);
		CamEngineGammaStart(cfg.index);
		//ISPWbupdateGains(ISP_ENGINE_RGB);
		if (1 == image_ch->isp_cproc_enable)
			cproc_enable(cfg.index,image_ch->cproc_contrast, image_ch->cproc_brightness
							, image_ch->cproc_saturation, image_ch->cproc_hue);
		if (1 == image_ch->isp_flt_enable)
			flt_set_level(image_ch->isp_ch, image_ch->denoise_level, image_ch->sharpen_level);
	}

#if defined (SENSOR_PREVIEW_MODE)	
	isp_stop(1);
	cfg_isp_mi_buffer(1);
	isp_reg_write(1,MI_CTRL,0x2a306802);//0x2a356802
    isp_reg_write(1,MI_INIT,0x10);
#endif

    return 0;
}

int ir_image_channel_set(imageChannel_t *image_ch, bool isp_bypass, uint32_t i2c_num, uint32_t i2c_slave_addr)
{
	isp_sw_reset(image_ch->isp_ch);
	aos_msleep(1);
	mipi_config(image_ch);
	
	if (false == isp_bypass) 
	{
		CamEngineInstConfig_t cfg = {0};
		cfg.index = (CamEngineInstIndex_t)image_ch->isp_ch;
        cfg.i2c_num = i2c_num;
        cfg.i2c_slave_addr = i2c_slave_addr;
        isp_res_map(image_ch->in.res, (uint32_t *)&cfg.mp_cfg.width, (uint32_t *)&cfg.mp_cfg.height);
        isp_res_map(image_ch->out.res, (uint32_t *)&cfg.sp_cfg.width, (uint32_t *)&cfg.sp_cfg.height);
        cfg.crop_cfg.width = image_ch->crop_res_x;
        cfg.crop_cfg.height = image_ch->crop_res_y;
        cfg.camEngineType = ISP_ENGINE_IR;
        isp_format_map(image_ch->in.format, &cfg.inputSelection);
        
		IspEngineConfigStart(cfg.index, &cfg);
		//CamIrStartStreaming(cfg.index);
		CamIrStartStreaming(&cfg);
		if (1 == image_ch->isp_cproc_enable)
			cproc_enable(cfg.index,image_ch->cproc_contrast, image_ch->cproc_brightness
							, image_ch->cproc_saturation, image_ch->cproc_hue);
		if (1 == image_ch->isp_flt_enable)
			flt_set_level(image_ch->isp_ch, image_ch->denoise_level, image_ch->sharpen_level);
		//CamEngineGammaStart(ISP_ENGINE_IR);
	} 

#if defined (SENSOR_PREVIEW_MODE)	
	isp_stop(0);
	cfg_isp_mi_buffer(0);
#endif
    return 0;
}

void isp_res_map(image_res_e res, uint32_t *width, uint32_t *height)
{
	switch(res)
	{
		case R_640x360:
            *width   = 640;
            *height  = 360;
			break;
		case R_360x640:
            *width   = 360;
            *height  = 640;
			break;
		case R_640x400:
            *width   = 640;
            *height  = 400;
			break;
        case R_640x480:
            *width   = 640;
            *height  = 480;
            break;
        case R_720P:
            *width   = 1280;
            *height  = 720;
            break;
        case R_1280x800:
            *width   = 1280;
            *height  = 800;
            break;
        case R_1080P:
            *width   = 1920;
            *height  = 1080;
            break;
		case R_800x600:
			*width	 = 800;
			*height  = 600;
			break;
		case R_1600x1200:
			*width	 = 1600;
			*height  = 1200;
			break;
		case R_1080x1280:
			*width	 = 1080;
			*height  = 1280;
			break;
		case R_720x1280:
			*width	 = 720;
			*height  = 1280;
			break;
		default: 
            *width   = 0xffffffff;
            *height  = 0xffffffff;
			break;
	}
}

void isp_format_map(image_format_e       format, uint32_t *isp_format)
{
	switch(format)
	{
		case RAW8:
            *isp_format   = CAMERIC_ISP_INPUT_8BIT_ZZ;
			break;
		case RAW10:
            *isp_format   = CAMERIC_ISP_INPUT_10BIT_ZZ;
			break;
        case RAW12:
            *isp_format   = CAMERIC_ISP_INPUT_12BIT;
            break;
		default: 
            *isp_format   = CAMERIC_ISP_INPUT_10BIT_ZZ;
			break;
	}
}

int if_vWrite_calib_para(uint16_t *ir2_dep_x2, uint16_t *ir2_dep_y2, uint16_t *ir2_dep_tab2d)
{
	int ret = 0;
	// uint32_t offset = 0;

	if((NULL == ir2_dep_x2) || (NULL == ir2_dep_y2) || (NULL == ir2_dep_tab2d))
		return -1;

	// ret = qspi_flash_write(QSPI_IR2_DEP_X2_ADR, (char *)ir2_dep_x2, IR2_DEP_X2_LEN);
	// ret = qspi_flash_write(QSPI_IR2_DEP_Y2_ADR, (char *)ir2_dep_x2, IR2_DEP_Y2_LEN);
	// ret = qspi_flash_write(QSPI_IR2_DEP_TAB2D_ADR, (char *)ir2_dep_x2, IR2_DEP_TAB2D_LEN);

	printf("write calib para: \n");
#if 0
	if_vErase_calib_para();
	offset = QSPI_IR2_DEP_X2_OFFSET;
	ret += hal_flash_write(HAL_PARTITION_APPLICATION, &offset, ir2_dep_x2, IR2_DEP_X2_LEN);
	offset = QSPI_IR2_DEP_Y2_OFFSET;
	ret += hal_flash_write(HAL_PARTITION_APPLICATION, &offset, ir2_dep_y2, IR2_DEP_Y2_LEN);
	offset = QSPI_IR2_DEP_TAB2D_OFFSET;
	ret += hal_flash_write(HAL_PARTITION_APPLICATION, &offset, ir2_dep_tab2d, IR2_DEP_TAB2D_LEN);

	if(ret)
		printf("write calib para err! \n");
#endif
	return ret;
}

int if_vRead_calib_para(void)
{
	int ret = 0;
	// uint32_t offset = 0;

	printf("read calib para: \n");
#if 0
	offset = QSPI_IR2_DEP_X2_OFFSET;
	//ret += hal_flash_read(HAL_PARTITION_APPLICATION, &offset, (uint8_t *)g_variable_cfg.ir2_dep_x2, IR2_DEP_X2_LEN);
	ret += indirect_memcpy_dma_linked((uint8_t *)g_variable_cfg.ir2_dep_x2, (uint8_t *)APPLICATION_PARTITION_START+offset, IR2_DEP_X2_LEN);
	check_flash_data_move_done();

	offset = QSPI_IR2_DEP_Y2_OFFSET;
	//ret += hal_flash_read(HAL_PARTITION_APPLICATION, &offset, (uint8_t *)g_variable_cfg.ir2_dep_y2, IR2_DEP_Y2_LEN);
	ret += indirect_memcpy_dma_linked((uint8_t *)g_variable_cfg.ir2_dep_y2, (uint8_t *)APPLICATION_PARTITION_START+offset, IR2_DEP_Y2_LEN);
	check_flash_data_move_done();

	offset = QSPI_IR2_DEP_TAB2D_OFFSET;
	ret += hal_flash_read(HAL_PARTITION_APPLICATION, &offset, (uint8_t *)g_variable_cfg.ir2_dep_tab2d, IR2_DEP_TAB2D_LEN);
	//ret += indirect_memcpy_dma((uint8_t *)g_variable_cfg.ir2_dep_tab2d, (uint8_t *)APPLICATION_PARTITION_START+offset, IR2_DEP_TAB2D_LEN);
	//check_flash_data_move_done();

	if(ret)
		printf("read calib para err! \n");
#endif
	return ret;
}

int if_vErase_calib_para(void)
{
	int ret = 0;

	printf("erase calib para: \n");
#if 0
	ret += hal_flash_erase(HAL_PARTITION_APPLICATION, QSPI_IR2_DEP_X2_OFFSET, IR2_DEP_X2_LEN);
	ret += hal_flash_erase(HAL_PARTITION_APPLICATION, QSPI_IR2_DEP_Y2_OFFSET, IR2_DEP_Y2_LEN);
	ret += hal_flash_erase(HAL_PARTITION_APPLICATION, QSPI_IR2_DEP_TAB2D_OFFSET, IR2_DEP_TAB2D_LEN);

	if(ret)
		printf("erase calib para err! \n");
#endif
	return ret;
}


int if_vCalibration_initial()
{
    uint8_t cal[10] = {0};
    int len = sizeof(cal);

	g_variable_cfg.ir2_dep_x2 = NULL;
	g_variable_cfg.ir2_dep_y2 = NULL;
	g_variable_cfg.ir2_dep_tab2d = NULL;

	g_variable_cfg.ir2_dep_x2 = (uint16_t *)aos_malloc(640 * 360 * 2 * sizeof(uint16_t));
	if (NULL == g_variable_cfg.ir2_dep_x2)
	{
		printf("Failed to allocate memory. %s %d\r\n", __func__, __LINE__);
	}

	g_variable_cfg.ir2_dep_y2 = (uint16_t *)aos_malloc(640 * 360 * sizeof(uint16_t));
	if (NULL == g_variable_cfg.ir2_dep_y2)
	{
		printf("Failed to allocate memory. %s %d\r\n", __func__, __LINE__);
	}

	g_variable_cfg.ir2_dep_tab2d = (uint16_t *)aos_malloc(4096 * sizeof(uint16_t));
	if (NULL == g_variable_cfg.ir2_dep_tab2d)
	{
		printf("Failed to allocate memory. %s %d\r\n", __func__, __LINE__);
	}

    int ret = aos_kv_get(CALIBRATION_KV_STATE, cal, &len);
    if (ret)
    {
        printf("Failed to load cal init mode of sensor %d \n", ret);
        g_variable_cfg.g_sensorCalState = 0;
    }else{
        if(strstr((char *)cal,"CAL")){
			if_vRead_calib_para();
			g_variable_cfg.g_sensorCalState=1;
		}  
        else 
            g_variable_cfg.g_sensorCalState=0;
    }

	ifv_printf(IFV_MSG_ERROR,"Enter %s state %d\r\n", __func__, g_variable_cfg.g_sensorCalState);

	return ret;
}

int if_vCalibration_state()
{
    return g_variable_cfg.g_sensorCalState;

}

algo_rectify_output_t* if_vCalibration_check(int h, int w, void *img_l, RectifyPoint *lp,void *img_r, RectifyPoint *rp)
{
	int ret = 0;
	algo_rectify_output_t *result = NULL;
    // cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	
    if(!g_variable_cfg.g_sensorCalState){
		result = TSM_ALGO_CalibOnLineRun(NULL, h, w, 18.0, FOCAL_LENGTH_3D, img_l, lp, img_r, rp);
		
		tsmTRP_Sl3dCfg_t sl3d_cfg_newc =
		{
			0,1,
			{640,360,0,TRP_SAD_WIN_SIZE_13,true},
			{80,80*13*13},
			{640,360,NULL,result->ir2_depth_Y2,NULL,result->ir2_depth_X2,result->ir2_depth_tab2d},
			//{640,360,NULL,NULL,NULL,NULL,NULL},
			{0,40,8,0},
			{1,20.0f},
			{TRP_DISP_RANGE_NEG_32_8160,4000},
			{-1.0f, 18.0, FOCAL_LENGTH_3D, 0},
			TRP_SL3D_DEBUG_MAX_MODULE,
		};

		ret = TSM_ALGO_InitSl3dDepth_doubleIR(&sl3d_cfg_newc);
		if (ret != 0) {
			LOGE("iva", "sl3d init:%d\n", ret);
		}
    }
	
	return result;
}

int if_vCalibration_bak(algo_rectify_output_t *result)
{
	if(NULL == result){
		printf("parameter is null \n");
		return -1;
	}
		
	memcpy(g_variable_cfg.ir2_dep_x2, result->ir2_depth_X2, 640*360*2*2);
	memcpy(g_variable_cfg.ir2_dep_y2, result->ir2_depth_Y2, 640*360*2);
	memcpy(g_variable_cfg.ir2_dep_tab2d, result->ir2_depth_tab2d, 4096*2);

	// if(memcmp(g_variable_cfg.ir2_dep_x2, result->ir2_depth_X2, 640*360*2*2))
	// 	printf("copy x2 error \n");
	// else if(memcmp(g_variable_cfg.ir2_dep_y2, result->ir2_depth_Y2, 640*360*2))
	// 	printf("copy y2 error \n");
	// else	
	// 	printf("copy correct \n");

	return 0;
}


int if_vCalibration_save(void)
{
	int ret = 0;
	uint8_t cal[10] = "CAL";
    uint32_t len = sizeof(cal);

	if(g_variable_cfg.g_calib_not_save_flag){
		g_variable_cfg.g_sensorCalState = 1;
		return 0;
	}
	
	//save calibration parameter
	ret = if_vWrite_calib_para(g_variable_cfg.ir2_dep_x2, g_variable_cfg.ir2_dep_y2, g_variable_cfg.ir2_dep_tab2d);
	if (ret)
	{
		printf("Failed to save calib para %d \n", ret);
		return -1;
	}else
		printf("save calib para ok. \n");
	
	ret = aos_kv_set(CALIBRATION_KV_STATE, cal, len,1);
	if (ret)
	{
		printf("Failed to load cal init mode of sensor %d \n", ret);
		return -1;
	}else
		printf("cal ok. \n");

	g_variable_cfg.g_sensorCalState = 1;

	return ret;
}


int if_vCalibration_process(int timeout)
{
	// int ret=0; 
	// int openmax_ir_mode;
	// int openmax_3d_mode;
	cmd2openmax_list *cmd2openmax = &g_ifv2openmax_recognize_cmd;
	// cmd2openmax_list *cmd2openmax_reg = &g_ifv2openmax_register_cmd;	

	ifv_printf(IFV_MSG_INFO,"Enter %s state %d\r\n", __func__, cmd2openmax->state);
    	
	while( (cmd2openmax->state != APP2IFV_CMD_STATE_NONE ) 
		&& (cmd2openmax->state != APP2IFV_RECOGNIZE_CMD_STATE_COMPLETE))
	{
		ifv_printf(IFV_MSG_INFO," %s recogn state %d r\n", __func__,cmd2openmax->state );
		aos_msleep(10);	
	}
        
	memset(cmd2openmax,0,sizeof(cmd2openmax_list));

    cmd2openmax->state = APP2IFV_CALIBRATION_CMD_STATE_ENTRY;
	ifv_printf(IFV_MSG_INFO," do %s\r\n", __func__);

	if ((g_ifv_flow_cfg.source_ir_left) && (g_ifv_flow_cfg.source_ir_right))
	{
        clearAEConvergentStatus();
		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type = LED_LIGHT_TYPE_IR;
		irreco_enable_flag = 1;
        if(irreco_exp_init_done == 0)
        {
            ifv_setIspexp(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            ifv_setIspexp(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
            //ifv_setIspSetPoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id);
            //ifv_setIspSetPoint(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id);
            irreco_exp_init_done = 1;
        }
		qw_isp_ae_lock_judge_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
		qw_isp_ae_lock_judge_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, true);
        qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, true);
        qw_isp_ae_enable_set(TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, true);
		if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id, \
			TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].light_type); 

		TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type = LED_LIGHT_TYPE_IR;
        if_vIrStreamPauseResume(ISP_IR_STREAM_RESUME,\
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].mipi_id, \
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].isp_id, \
            TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_RIGHT].light_type);
	}
	
    return 0;
}

extern float face_param_livingNirThres ;
extern float face_param_living3DThres ;
extern float face_param_faceMatchThres ;
extern float g_matchparam_threshold;
extern float g_matchparam_mask_threshold;

int ifv_kv_load()
{
    int ret=0;
    //1
    ret = ifv_GetAieReasultPrintParamKV();
    
    //2
	ret = ifv_GetAieRunModeParamKV();
    
    //3
    ifv_load_aie_thres(&face_param_livingNirThres, 
                       &face_param_living3DThres, 
                       &face_param_faceMatchThres,
                       NULL);

    //4
    ifv_load_aie_thres(NULL, 
                       NULL, 
                       &g_matchparam_threshold,
                       NULL);
    //5
    ifv_load_aie_thres(NULL, 
                       NULL, 
                       NULL,
                       &g_matchparam_mask_threshold);

	return ret;
}
 
void if_vFace_ae_clean()
{
	memset(g_face_ae_info.nirBox, 0x00, sizeof(TsmFaceBox) * ISP_NUM);
	memset(g_face_ae_info.meanLuma_face, 0x00, sizeof(uint32_t) * ISP_NUM);
	memset(g_face_ae_info.meanLuma_isp, 0x00, sizeof(uint32_t) * ISP_NUM);
	memset(g_face_ae_info.nirFace, 0x00, sizeof(uint32_t) * ISP_NUM);
	g_face_ae_info.loop_counter = 1;
	g_face_ae_info.inProcess = 0;
}
